Your Guide to Laravel Excellence

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.

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:

<?php
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;
}

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:

<?php
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(),

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:

<?php
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:

<?php
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.

Recommeded Posts

Learn about the toBase() method in Laravel - Full Guide & Examples

Learn about the toBase() method in Laravel - Full Guide & Examples

Learn about the toBase() method in Laravel - Full Guide & Examples

1 month ago Read article →
How to Add Real-Time Comments in Laravel 11 with Laravel Reverb

How to Add Real-Time Comments in Laravel 11 with Laravel Reverb

How to Add Real-Time Comments in Laravel 11 with Laravel Reverb

1 month ago Read article →
Using spatie/browsershot in Laravel for Screenshot and PDF Generation

Using spatie/browsershot in Laravel for Screenshot and PDF Generation

Learn how to use the Spatie Browsershot package in Laravel to capture screenshots and generate PDFs easily. This guide walks you through the setup process and shows you how to create high-quality images and documents from your web pages.

1 month ago Read article →
LinkedIn OAuth Authentication in Laravel Without Socialite

LinkedIn OAuth Authentication in Laravel Without Socialite

LinkedIn OAuth Authentication in Laravel Without Socialite

1 month ago Read article →