Role-Based Redirects in Laravel Fortify with Spatie Permissions

Role-Based Redirects in Laravel Fortify with Spatie Permissions

In this guide, you'll learn how to implement role-based redirects in Laravel Fortify using Spatie's permissions package. First, we'll show you how to use an anonymous class to customize the login response. This means we can redirect users to different URLs after they log in, depending on their roles.Then, we'll explain how to create a dedicated class for this purpose. This can make your code more organized and easier to maintain in the long run.

By the end of this tutorial, you'll be able to redirect users to different URLs based on their roles after they log in.

1. Setting Up Spatie Permissions

Before we start, ensure you have the Spatie permissions package installed and configured in your Laravel project. If not, you can install it using Composer:

composer require spatie/laravel-permission php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" php artisan migrate

Configure your User model to use the  HasRoles  trait:

namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Spatie\Permission\Traits\HasRoles; class User extends Authenticatable { use HasRoles; }

2. Creating a Custom Login Response

Using an Anonymous Class : In your FortifyServiceProvider, you can define a custom login response using an anonymous class. This allows you to implement role-based redirection logic directly within the service provider.

In your app/Providers/FortifyServiceProvider.php, add the following code:

namespace App\Providers; use Illuminate\Http\Request; use Illuminate\Support\ServiceProvider; use Laravel\Fortify\Fortify; use Laravel\Fortify\Contracts\LoginResponse; class FortifyServiceProvider extends ServiceProvider { public function register() { $this->app->instance(LoginResponse::class, new class implements LoginResponse { public function toResponse($request) { $user = $request->user(); if ($user->hasRole('Moderator')) { return redirect('/moderator'); } return redirect('/home'); } }); } public function boot() { Fortify::authenticateUsing(function (Request $request) { $user = \App\Models\User::where('email', $request->email)->first(); if ($user && \Illuminate\Support\Facades\Hash::check($request->password, $user->password)) { return $user; } }); } }

Register Method: Here, we use an anonymous class to implement the LoginResponse interface. The toResponse method checks the user's role and redirects them accordingly.

Boot Method: This method customizes the authentication process by checking the user's credentials

Ensure Fortify is Registered

Make sure that FortifyServiceProvider is included in your config/app.php under the providers array:

'providers' => ServiceProvider::defaultProviders()->merge([ /* * Other Service Providers */ Spatie\Permission\PermissionServiceProvider::class, ])->toArray(),

3. Dedicated Class for Custom Login Response

If you prefer to keep your code clean and maintainable, you can create a dedicated class for the custom login response.

Create Custom Login Response Class : First, create a new class to handle the login response:

namespace App\Http\Responses; use Laravel\Fortify\Contracts\LoginResponse as LoginResponseContract; class LoginResponse implements LoginResponseContract { public function toResponse($request) { $user = $request->user(); if ($user->hasRole('Moderator')) { return redirect('/moderator'); } return redirect('/home'); } }

Update FortifyServiceProvider

Next, update your FortifyServiceProvider to use this custom login response class:

namespace App\Providers; use Illuminate\Http\Request; use Illuminate\Support\ServiceProvider; use Laravel\Fortify\Fortify; use App\Http\Responses\LoginResponse as CustomLoginResponse; use Laravel\Fortify\Contracts\LoginResponse; class FortifyServiceProvider extends ServiceProvider { public function register() { $this->app->singleton(LoginResponse::class, CustomLoginResponse::class); } public function boot() { Fortify::authenticateUsing(function (Request $request) { $user = \App\Models\User::where('email', $request->email)->first(); if ($user && \Illuminate\Support\Facades\Hash::check($request->password, $user->password)) { return $user; } }); // Other Fortify customizations... } }

Explanation

Custom Login Response Class: This class implements Fortify's LoginResponse contract and defines the redirection logic based on user roles.

FortifyServiceProvider: Registers the custom login response class in the register method.

Tags
Laravel Fortify Multi Auth Laravel Fortify Role Redirect Laravel Fortify Laravel 11 Different Roles Laravel Fortify Laravel Fortify Redirect User