Table Of Contents
Laravel's Built-in Solution: Custom Guard Configuration
Laravel allows creating custom guards in config/auth.php
with different drivers and providers for specialized authentication needs like admin panels or API endpoints.
// config/auth.php - Add custom guards
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
// Custom admin guard
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
// Custom API guard for admins
'admin-api' => [
'driver' => 'token',
'provider' => 'admins',
'hash' => false,
],
// JWT guard (requires package)
'jwt' => [
'driver' => 'jwt',
'provider' => 'users',
],
// Custom driver guard
'custom' => [
'driver' => 'custom-driver',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// Custom admin provider
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
// Database provider for custom table
'api_users' => [
'driver' => 'database',
'table' => 'api_users',
],
],
// Admin model for custom guard
class Admin extends Authenticatable
{
use HasFactory, Notifiable;
protected $fillable = [
'name', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
// Define admin-specific methods
public function isSuperAdmin()
{
return $this->role === 'super_admin';
}
}
// Admin migration
Schema::create('admins', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('role')->default('admin');
$table->rememberToken();
$table->timestamps();
});
// Admin authentication controller
class AdminAuthController extends Controller
{
public function showLoginForm()
{
return view('admin.auth.login');
}
public function login(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('/admin/dashboard');
}
return back()->withErrors([
'email' => 'The provided credentials do not match our records.',
]);
}
public function logout(Request $request)
{
Auth::guard('admin')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/admin/login');
}
}
// Admin routes with custom guard
Route::prefix('admin')->group(function () {
Route::get('/login', [AdminAuthController::class, 'showLoginForm'])->name('admin.login');
Route::post('/login', [AdminAuthController::class, 'login']);
Route::post('/logout', [AdminAuthController::class, 'logout'])->name('admin.logout');
Route::middleware('auth:admin')->group(function () {
Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard');
Route::resource('/users', AdminUserController::class);
});
});
// Middleware for admin guard
class AdminMiddleware
{
public function handle($request, Closure $next)
{
if (!Auth::guard('admin')->check()) {
return redirect()->route('admin.login');
}
return $next($request);
}
}
// Register middleware in Kernel.php
protected $routeMiddleware = [
// ... other middleware
'admin' => \App\Http\Middleware\AdminMiddleware::class,
];
// Using custom guard in controllers
class AdminController extends Controller
{
public function __construct()
{
$this->middleware('auth:admin');
}
public function dashboard()
{
$admin = Auth::guard('admin')->user();
return view('admin.dashboard', compact('admin'));
}
public function profile()
{
// Multiple ways to access admin user
$admin1 = Auth::guard('admin')->user();
$admin2 = auth('admin')->user();
$admin3 = request()->user('admin');
return view('admin.profile', compact('admin1'));
}
}
// Custom guard driver
class CustomGuard implements Guard
{
protected $provider;
protected $user;
protected $request;
public function __construct(UserProvider $provider, Request $request)
{
$this->provider = $provider;
$this->request = $request;
}
public function check()
{
return !is_null($this->user());
}
public function guest()
{
return !$this->check();
}
public function user()
{
if (!is_null($this->user)) {
return $this->user;
}
$token = $this->request->header('X-API-TOKEN');
if ($token) {
$this->user = $this->provider->retrieveByCredentials([
'api_token' => hash('sha256', $token)
]);
}
return $this->user;
}
public function id()
{
return $this->user() ? $this->user()->getAuthIdentifier() : null;
}
public function validate(array $credentials = [])
{
if (empty($credentials['api_token'])) {
return false;
}
$user = $this->provider->retrieveByCredentials($credentials);
return !is_null($user);
}
public function hasUser()
{
return !is_null($this->user);
}
public function setUser(Authenticatable $user)
{
$this->user = $user;
return $this;
}
}
// Register custom guard driver
// In AuthServiceProvider
public function boot()
{
Auth::extend('custom-driver', function ($app, $name, array $config) {
return new CustomGuard(
Auth::createUserProvider($config['provider']),
$app->make('request')
);
});
}
// API authentication with custom guard
Route::middleware('auth:api')->group(function () {
Route::get('/user', function (Request $request) {
return $request->user('api');
});
Route::apiResource('/posts', PostApiController::class);
});
// Multi-guard authentication
class MultiGuardController extends Controller
{
public function profile(Request $request)
{
// Check multiple guards
if ($user = $request->user('web')) {
return $this->webUserProfile($user);
}
if ($admin = $request->user('admin')) {
return $this->adminProfile($admin);
}
if ($apiUser = $request->user('api')) {
return $this->apiUserProfile($apiUser);
}
return response()->json(['error' => 'Unauthenticated'], 401);
}
}
// Sanctum integration with custom guards
// config/sanctum.php
'guard' => ['web', 'admin'],
// Use Sanctum with admin guard
Route::middleware('auth:sanctum,admin')->group(function () {
Route::get('/admin-api/stats', [AdminApiController::class, 'stats']);
});
// Testing custom guards
class CustomGuardTest extends TestCase
{
public function test_admin_can_login()
{
$admin = Admin::factory()->create([
'email' => 'admin@example.com',
'password' => Hash::make('password'),
]);
$response = $this->post('/admin/login', [
'email' => 'admin@example.com',
'password' => 'password',
]);
$response->assertRedirect('/admin/dashboard');
$this->assertTrue(Auth::guard('admin')->check());
}
public function test_admin_middleware_protects_routes()
{
$response = $this->get('/admin/dashboard');
$response->assertRedirect('/admin/login');
}
public function test_api_guard_with_token()
{
$user = User::factory()->create([
'api_token' => hash('sha256', 'test-token'),
]);
$response = $this->withHeader('Authorization', 'Bearer test-token')
->getJson('/api/user');
$response->assertStatus(200);
$response->assertJson(['id' => $user->id]);
}
}
// Guard helper methods
class GuardHelper
{
public static function getCurrentGuard()
{
foreach (config('auth.guards') as $guard => $config) {
if (Auth::guard($guard)->check()) {
return $guard;
}
}
return null;
}
public static function getCurrentUser()
{
$guard = self::getCurrentGuard();
return $guard ? Auth::guard($guard)->user() : null;
}
}
// Blade directives for custom guards
// In AppServiceProvider
public function boot()
{
Blade::if('admin', function () {
return Auth::guard('admin')->check();
});
Blade::if('superadmin', function () {
return Auth::guard('admin')->check() &&
Auth::guard('admin')->user()->isSuperAdmin();
});
}
// Usage in Blade templates
@admin
<p>Welcome, Admin {{ auth('admin')->user()->name }}!</p>
@endadmin
@superadmin
<a href="/admin/system">System Settings</a>
@endsuperadmin
// Multiple authentication forms
{{-- Regular user login --}}
<form method="POST" action="{{ route('login') }}">
@csrf
{{-- form fields --}}
</form>
{{-- Admin login --}}
<form method="POST" action="{{ route('admin.login') }}">
@csrf
{{-- form fields --}}
</form>
// JWT guard implementation (with tymon/jwt-auth)
// config/auth.php
'jwt' => [
'driver' => 'jwt',
'provider' => 'users',
],
// JWT controller
class JWTAuthController extends Controller
{
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if (!$token = Auth::guard('jwt')->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return response()->json(['token' => $token]);
}
public function me()
{
return response()->json(Auth::guard('jwt')->user());
}
public function logout()
{
Auth::guard('jwt')->logout();
return response()->json(['message' => 'Successfully logged out']);
}
}
// Console commands with guards
class CreateAdminCommand extends Command
{
protected $signature = 'admin:create {email} {name} {password}';
public function handle()
{
Admin::create([
'email' => $this->argument('email'),
'name' => $this->argument('name'),
'password' => Hash::make($this->argument('password')),
]);
$this->info('Admin created successfully');
}
}
// Guard-specific policies
class AdminPostPolicy
{
public function view(Admin $admin, Post $post)
{
return true; // Admins can view all posts
}
public function delete(Admin $admin, Post $post)
{
return $admin->isSuperAdmin();
}
}
// Register policies for different guards
// In AuthServiceProvider
protected $policies = [
Post::class => [
'admin' => AdminPostPolicy::class,
'web' => PostPolicy::class,
],
];
Custom Guard Implementation in Laravel 11
Define custom guards in config/auth.php
with specific drivers and providers. Create dedicated models, controllers, and middleware for each authentication context like admin panels or API endpoints.
In Laravel 8 through 11, guards provide isolation between different user types and authentication methods. Use custom providers for different database tables or authentication sources.
Common use cases: "Admin authentication", "API token authentication", "Multi-tenant systems", "External authentication providers". Always implement proper middleware and route protection for each guard.
Alternative approaches include using Laravel Sanctum for unified authentication, implementing OAuth2 servers for third-party integration, or using external authentication services like Auth0 or Firebase.
Add Comment
No comments yet. Be the first to comment!