ageekdev/dev-login
A Laravel package for quick developer login, letting you authenticate as any user during local development so you can test role-based flows without passwords. Useful for debugging and demos.
Install as a dev-only dependency so it never ships to production:
composer require ageekdev/dev-login --dev
Publish the config (tag name may vary by version — check vendor/ageekdev/dev-login/config if the tag fails):
php artisan vendor:publish --tag="dev-login-config"
Open config/dev-login.php first. That file is the whole package contract — it typically controls whether the feature is enabled, which environments it is allowed in, and which users/guards can be impersonated. Read it before touching routes or views.
The fastest first use case: in local, start the server, seed a couple of users (php artisan db:seed), and use the package's login route/UI to switch into a non-admin user. This is the moment the package earns its keep — instead of remembering test passwords, you click a user and you're in.
Verify it's inert where it matters before anything else:
php artisan config:clear
# in .env
APP_ENV=production php artisan route:list | grep -i dev-login # should be empty
If that route shows up under production, stop and fix the guard before continuing.
Route-based impersonation for QA flows. The usual pattern is a dev-only route that accepts a user identifier and logs you in. Use it as your "who am I now" switcher while building role-gated UI (admin dashboards, author-only buttons, subscription tiers). Log out between switches unless the package explicitly regenerates the session — see Gotchas.
Config allowlisting instead of open access. Even in local, scope the package to known users or emails:
// config/dev-login.php (shape will vary by version)
'enabled' => env('DEV_LOGIN_ENABLED', false),
'allowed' => ['[email protected]', '[email protected]'],
'guards' => ['web'],
Pair this with DEV_LOGIN_ENABLED=true in .env.local only. This gives you a second line of defence if a staging deploy accidentally picks up local config.
Seeders + dev-login = reproducible personas. Define one seeder that creates an admin, an editor, and a viewer. Then dev-login becomes a deterministic persona switcher, which is exactly what you want when writing feature tests or demoing to stakeholders.
Floating panel / Blade integration. Many dev-login packages ship a small UI you can drop into your layout. Wrap it so it can never render outside local:
@env('local')
@if(config('dev-login.enabled'))
<x-dev-login::panel />
@endif
@endenv
Never rely on the package's own environment check alone — belt and braces.
Multi-guard setups. If your app has web and admin guards, decide per-guard whether dev-login applies. Logging into the wrong guard is the most common source of "it says I'm logged in but I'm still redirected to /login" confusion. Configure the guard list explicitly rather than relying on the default.
Browser test shortcuts. Use the dev-login route in Dusk/Pest browser tests to skip the login form when you're testing something downstream of authentication. Keep one or two full login-form tests so you don't lose coverage of the real flow.
--dev doesn't protect you from config cache. Composer will not install the package in production, but a stale bootstrap/cache/config.php copied or built in the wrong environment can still reference dev-login.* keys and crash on boot. Always run php artisan config:cache in the target environment, never copy it.
Environment checks are not permission checks. APP_ENV=staging is not "local." Many people enable dev-login on staging so QA can hop accounts — that is a real security decision. If you must, restrict to specific IPs at the web server or via middleware, not via the package config.
Session and remember-me behaviour. Logging in as a user via a dev route may leave the previous remember_token cookie intact. If you switch accounts and find yourself bouncing back to the old user after a refresh, clear cookies or check whether the package calls Auth::logout() and session()->regenerate() first. When in doubt, add an explicit logout step in your dev workflow.
Route caching hides routes. If route:cache was run earlier, newly registered dev routes won't appear until you route:clear. Conversely, a dev route cached while enabled can persist after you disable it. Treat this as the #1 debugging step when "the route 404s in local but the file is fine."
Middleware order matters. If you have global middleware that enforces onboarding, 2FA, or email verification, dev-login can appear to "fail" when actually you're being redirected straight to /2fa or /onboarding. Temporarily disable those middleware in local, or configure the package to bypass them, otherwise you'll waste an afternoon.
Debugging checklist when a login goes nowhere:
APP_ENV — is it actually local?config('dev-login.enabled') — dump it.Auth::guard('admin')->check() vs Auth::check().php artisan route:list | grep dev-login.array driver means login won't survive the request; use file or database in local.Extension points to look for in the source. Since the package is small and lightly used (9 stars, 0 dependents), expect to read the source rather than the docs. The likely seams are: the route registration (override in your own RouteServiceProvider if needed), the "who can I log in as" resolver (point it at a scoped query or an allowlist), and the response after login (redirect target). Fork or wrap these rather than editing vendor/, and pin the version in composer.json so a patch release can't silently widen the allowlist.
Version and maintenance risk. With a small user base, treat the package as a convenience, not infrastructure. Keep your own fallback (Auth::loginUsingId($id) inside a local-only route) ready in case it's abandoned or a Laravel upgrade breaks it. It's a 30-line feature to replace; don't let it become load-bearing.
How can I help you explore Laravel packages today?