0

Email verification — MustVerifyEmail contract

Intermediate5 min read·lv-16-007

Concept

Multi-guard authentication enables different user types (customers, admins, staff) to authenticate against separate tables, with independent session management. Each guard has its own provider and session namespace.

Why multiple guards: A User and an Admin model may be in separate tables with different columns, different password requirements, and different capabilities. Mixing them in one table leads to complexity. Separate guards cleanly isolate the two authentication flows.

Configuration: Each guard in config/auth.php needs a driver and provider. Each provider needs a model (for Eloquent) or table (for database driver).

Accessing a specific guard: auth('admin') or Auth::guard('admin'). auth() with no arg uses the default guard.

Per-guard middleware: auth:admin — protects a route requiring the admin guard to be authenticated. auth (no arg) uses the default guard.

Auth::shouldUse('guard-name'): Switches the default guard for the current request. Useful in middleware that runs early in the pipeline.

Session isolation: Each guard stores its session under a different key (login_web_* for the web guard, login_admin_* for an admin guard). A user can be logged in to both simultaneously.

Common pattern: web guard for customers, admin guard for staff. Separate login pages, separate dashboards, separate session cookies.

Code Example

php
<?php
// config/auth.php
'guards' => [
    'web' => [
        'driver'   => 'session',
        'provider' => 'users',
    ],
    'admin' => [
        'driver'   => 'session',
        'provider' => 'admins',   // separate provider
    ],
    'api' => [
        'driver'   => 'sanctum',
        'provider' => 'users',
    ],
],

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model'  => \App\Models\User::class,
    ],
    'admins' => [
        'driver' => 'eloquent',
        'model'  => \App\Models\Admin::class,  // separate model + table
    ],
],

// Admin model — must implement Authenticatable
class Admin extends \Illuminate\Foundation\Auth\User
{
    protected $table = 'admins';
    protected $guard = 'admin'; // optional hint
}

// Login for admin guard
class AdminLoginController extends Controller
{
    public function store(Request $request)
    {
        $credentials = $request->validate([
            'email'    => 'required|email',
            'password' => 'required',
        ]);

        if (Auth::guard('admin')->attempt($credentials, $request->boolean('remember'))) {
            $request->session()->regenerate();
            return redirect()->intended(route('admin.dashboard'));
        }

        return back()->withErrors(['email' => 'Invalid admin credentials.']);
    }
}

// Route protection by guard
Route::middleware('auth:admin')->prefix('admin')->group(function() {
    Route::get('/dashboard', AdminDashboardController::class)->name('admin.dashboard');
    Route::resource('users', AdminUserController::class);
});

// In controllers — specify guard
public function dashboard()
{
    $admin = auth('admin')->user();   // Admin model
    $user  = auth()->user();          // User model (default 'web' guard)

    auth('admin')->check();           // is admin logged in?
    auth('admin')->logout();          // log out from admin guard only
}