›
›
›
  1. docs
  2. ›
  3. byrcsc/laravel-dev-login
1.x
Browse documentationOpenClose

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Profiles
  • Safety gates
  • The login flow

Extending

  • User resolvers
  • Tenancy
  • Routes and redirects
  • Customizing the page

Reference

  • Configuration
  • Testing
  • Troubleshooting

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Profiles
  • Safety gates
  • The login flow

Extending

  • User resolvers
  • Tenancy
  • Routes and redirects
  • Customizing the page

Reference

  • Configuration
  • Testing
  • Troubleshooting

byrcsc/laravel-dev-login · 1.x

Safety gates.

Five independent checks decide whether the dev login page exists, and all five have to agree.

The package puts a page on your application that logs anybody in without a password. Whether that page exists is decided by five separate checks. None of them is "it was installed with --dev", and none of them can be satisfied by another one being satisfied.

Three are answered while the application boots, and they decide whether the routes register at all. One is a refusal that stops the boot. One is answered per request, because it depends on something no config file knows.

1. The enable flag

'enabled' => (bool) env('DEV_LOGIN_ENABLED', false),

Off by default. Turning it on is something a developer does on purpose, in their own .env, on their own machine.

It is deliberately separate from the environment allowlist below. Being in local is never on its own enough to expose this page, so both have to say yes.

2. The environment allowlist

'environments' => ['local', 'testing'],

The environments the package may run in at all, matched case-sensitively against app()->environment().

Staging is not on the list on purpose. A team that wants it writes it in, which is an edit somebody reviews rather than a default nobody notices:

'environments' => ['local', 'testing', 'staging'],

Config this check cannot read as a list is treated as an empty list. A malformed value shuts the gate rather than opening it.

3. The production refusal

production is not a value this list accepts. Naming it while the enable flag is on throws DevLoginEnabledInProduction at boot:

Dev login is enabled while APP_ENV=production. Refusing to boot. Remove
DEV_LOGIN_ENABLED from the production environment, or set it to false.

The production check is asked separately from the allowlist, so the list cannot be edited into an override. It also matches case-insensitively, unlike the allowlist, so an APP_ENV=Production cannot slide past it.

This is loud on purpose. An application that reaches production with the flag on has a deployment problem, and it should find out from a failed boot rather than from a stranger on the login page. A silent no-op is indistinguishable from a package that is working.

The refusal stops artisan as well as web requests, because both boot the same container. The way out is the environment file, not a cache command.

4. No routes when a gate says no

When the flag, the allowlist, or the production check disagrees, the routes are never registered. There is no GET /dev-login to forbid.

Every refusal is therefore a 404 rather than a 403. A 403 tells a stranger the page is there.

5. The allowed-hosts list

'allowed_hosts' => ['localhost', '127.0.0.1', '*.test'],

This is the one check that does not trust your application's own configuration. Everything above can be switched on by an .env that reaches the wrong machine. This is matched against the host the request actually arrived on, by middleware registered under the alias dev-login.host.

Matching rules:

  • Hosts are compared case-insensitively.
  • An entry with no wildcard matches that exact host and nothing else. localhost does not match localhost.evil.com.
  • A leading *. matches subdomains only. *.test covers acme.test and tenant.acme.test, but never test itself, and never acme.test.evil.com.
  • A bare * matches nothing. Wildcards only ever stand for the subdomain part, so a pattern that is neither an exact host nor *.something is a host nobody has.
  • An empty list allows nothing.

A host that fails aborts with 404, for the same reason the boot-time gates leave no route behind.

The environment badge

The page shows app()->environment() as a yellow badge next to your application name, above a line saying that anybody who can reach the page can sign in as any profile on it.

That is aimed at the person looking at the screen rather than at any request, and it is why the page is not themeable into something that could be mistaken for your real login. Publishing the views is the only customization the package offers, and there is no theming config.

The gates apply to the component too

<x-dev-login::profiles /> can be rendered from a route your application owns, where the package's own route registration is not involved. The component therefore asks the boot-time gates and the host gate again on its own account, and renders an empty string when either says no.

A list of ways into an application is not something to render on a host nobody allowed.

Checking a gate yourself

Gatekeeper is the class behind all of this, resolvable from the container:

use ByRcsc\LaravelDevLogin\Gatekeeper;

$gatekeeper = app(Gatekeeper::class);

$gatekeeper->passes();                    // all three boot-time gates agree
$gatekeeper->mustRefuseToBoot();          // enabled, and in production
$gatekeeper->hostIsAllowed('acme.test');  // the per-request gate, for one host

passes() is what route registration hangs on, and what the component checks before rendering.

What to read next

  • Configuration for the defaults and types of every key named here.
  • Troubleshooting to work out which gate is behind a 404.
  • Customizing the page to embed the component on a page of your own.
PreviousProfilesNextThe login flow
View source

On this page

  1. 1. The enable flag
  2. 2. The environment allowlist
  3. 3. The production refusal
  4. 4. No routes when a gate says no
  5. 5. The allowed-hosts list
  6. The environment badge
  7. The gates apply to the component too
  8. Checking a gate yourself
  9. What to read next