›
byrcsc/laravel-dev-login · 1.x
Move the page, add middleware to it, and control where each profile lands after a click.
The package registers two routes and nothing else:
| Method | URI | Name | Purpose |
|---|---|---|---|
GET | /dev-login | dev-login.show | Renders the page |
POST | /dev-login/{profile} | dev-login.attempt | Authenticates and redirects |
Both register only when the boot-time gates agree, and both carry the host gate as their last middleware. There is deliberately no GET route that authenticates, because a GET that logs you in can be fired by an image tag or a prefetch.
// config/dev-login.php
'path' => 'secret/way-in',Both routes move together. The page is now at GET /secret/way-in and the
buttons post to POST /secret/way-in/{profile}. The route names do not
change, so route('dev-login.show') keeps working.
The path must be a non-empty string. Anything else throws
InvalidConfiguration at boot, naming the key.
Moving the page is convenience, not security. The gates are what keep it shut.
'middleware' => ['web'],The list is applied to both routes, ahead of the package's own host gate.
web is the floor rather than a suggestion. The session guard needs a
session, and the POST route relies on that group for CSRF protection. Add to
this list, do not replace it:
'middleware' => ['web', 'ensure-vpn'],The value must be an array. A bare string throws InvalidConfiguration.
The host gate is appended after your list under the alias dev-login.host.
You can apply that alias to routes of your own:
use ByRcsc\LaravelDevLogin\DevLoginServiceProvider;
Route::middleware(DevLoginServiceProvider::HOST_MIDDLEWARE)
->get('/our-login', fn () => view('our-login'));The alias is registered whether or not the gates pass, so referencing it never breaks a route.
After authenticating, the controller redirects to the first of these that exists:
redirect.url.intended.default_redirect from config/dev-login.php./.'support' => [
'label' => 'Support',
'email' => 'support@example.com',
'redirect' => '/support/queue',
],This wins over everything else, including an intended URL. Use it for profiles that only make sense on one screen.
Laravel writes url.intended when its auth middleware turns an
unauthenticated request away. Hitting a guarded page, being sent to your login
route, and then clicking a dev login button lands you on the page you first
asked for.
The controller pulls the value, so it is consumed rather than left behind.
A tenant-bound profile skips this step. A URL captured in one tenant rarely means anything in another.
'default_redirect' => '/dashboard',Where profiles land when they name no redirect and there is no intended URL.
null falls through to /.
The controller calls redirect()->to($target) with the string from config.
Nothing validates or rewrites it, so a full URL works as well as a path.