packstub / account-switcher
Switch between accounts in a Laravel app without signing out: user impersonation with a banner and switch back, linked sub-accounts with password-confirmed escalation, one-click developer logins, and an audit log of every switch. packstub/filament-account-switcher adds the panel UI.
Fund package maintenance!
Requires
- php: ^8.2
- illuminate/contracts: ^12.0 || ^13.0
- spatie/laravel-package-tools: ^1.92
Requires (Dev)
- laravel/pint: ^1.27
- orchestra/testbench: ^10.0 || ^11.0
- pestphp/pest: ^4.0 || ^5.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-29 14:26:05 UTC
README
Switch between accounts in a Laravel app without signing out, safely, in production. Free and open source (MIT).
Impersonate a user to see what they see and switch back from a banner. Link the accounts one person owns and move between them, with the target account's password asked when switching up. Sign in with one click as a seeded account while you build. Every switch lands in an audit log and fires an event.
Works with any session guard: Breeze, Jetstream, Fortify, Inertia or your own login. Filament Account Switcher puts the same features into a Filament panel.
- Docs: packstub.dev/docs/account-switcher (the same pages live in
docs/) - Support: GitHub issues
Features
- Impersonation: a route and a facade to sign in as a user, a Blade banner with Switch back, rules on your model.
- Linked accounts: work from a low-privilege account and switch up to admin only when you need it, with the admin password.
- Developer logins: one-click sign-in buttons for your seeded accounts, only in the environments you allow; labels, tags, a runtime gate and a search hook for a menu of your own.
- Audit trail: every switch logged with who, why, guard, IP, user agent and the context you attach (the tenant, ...),
AccountSwitcher::log()for switches made elsewhere, plusAccountSwitchingandAccountSwitchedevents. - One session path: every switch re-authenticates your guard, regenerates the session and never sets "remember me".
- Multi-database aware: the two tables follow your user model's connection, so they stay central under multi-database tenancy.
Compatibility
| Package | Laravel | PHP |
|---|---|---|
| 1.x | 12.x, 13.x | 8.2+ |
Quick start
composer require packstub/account-switcher php artisan account-switcher:install
Only need impersonation and developer logins? Set features.linked_accounts and log_switches to false and skip the migrations and the trait (without migrations).
Add the trait and the rules to your user model:
use Packstub\AccountSwitcher\Concerns\HasLinkedAccounts; class User extends Authenticatable { use HasLinkedAccounts; public function canImpersonate(User $target): bool { return $this->is_admin; } public function canBeImpersonated(User $by): bool { return ! $this->is_admin; } }
Register the routes in routes/web.php:
use Packstub\AccountSwitcher\Facades\AccountSwitcher; AccountSwitcher::routes();
Put the banner in your layout and, if you want them, the developer login buttons on your login page:
<x-account-switcher::banner /> <x-account-switcher::developer-logins />
Then, from a users table:
<form method="POST" action="{{ route('account-switcher.impersonate', $user) }}"> @csrf <button type="submit">Impersonate</button> </form>
Or from code:
use Packstub\AccountSwitcher\Facades\AccountSwitcher; AccountSwitcher::impersonate($user); return redirect()->to(AccountSwitcher::redirectUrlFor($user));
Full walkthrough: Installation.
Linked accounts
$admin->linkAccount($daily, label: 'Daily', requiresPassword: false); AccountSwitcher::switchableAccounts($admin); // what the "Switch to" menu lists AccountSwitcher::switchToLinkedAccount($daily); // one click down AccountSwitcher::switchToLinkedAccount($admin, $password); // the admin password up
A POST to account-switcher.switch with account and password does the same from a form. Read more: Linked accounts and the security model.
Configuration
What fits in config lives in config/packstub-account-switcher.php (guard, features, redirects, the developer login list, the environment ceiling, the tables). Rules that need code go on the app context, from a service provider's boot():
use Packstub\AccountSwitcher\AppContext; $this->app->make(AppContext::class) ->canImpersonateUsing(fn (User $by, User $target): bool => $by->can('impersonate', $target)) ->canSwitchUsing(fn (User $from, User $to): bool => ! $to->is_locked) ->canAccessUsing(fn (User $user): bool => $user->is_active) ->redirectTo(fn (User $user): string => route('dashboard')) ->userLabelUsing(fn (User $user): string => $user->full_name) ->developerLoginUsersUsing(fn () => User::query()->where('role', 'developer')->get());
Read more: Configuration, including events, the switch log and the facade.
Documentation
Testing
composer test
Changelog
See the changelog.
Security vulnerabilities
Please e-mail support@packstub.dev rather than opening a public issue.
Credits
License
MIT. See the license file.