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

How to show old selected values in multiple select options in Laravel

How to show old selected values in multiple select options in Laravel

How to show old selected values in multiple select options in Laravel

2 months ago Read article →
Soft Deletes in Laravel: Using withTrashed() and onlyTrashed() in Eloquent Queries

Soft Deletes in Laravel: Using withTrashed() and onlyTrashed() in Eloquent Queries

Soft Deletes in Laravel: Using withTrashed() and onlyTrashed() in Eloquent Queries

2 months ago Read article →
Infinite Scroll in Laravel Using jQuery and AJAX

Infinite Scroll in Laravel Using jQuery and AJAX

Infinite Scroll in Laravel Using jQuery and AJAX

2 months ago Read article →
How to Accept Credit Card Payments in Laravel 12 Using Square

How to Accept Credit Card Payments in Laravel 12 Using Square

Learn how to easily add Square credit card payments to your Laravel 12 website. Step-by-step guide for secure and smooth payment integration.

1 month ago Read article →