Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

aymanmsh's avatar
Level 15

What is the best practice for implementing user roles in Laravel?

For example, my website has different types of users such as admin, manager, and student. How can I properly authorize each user to perform only the actions specific to their role?

0 likes
5 replies
LaryAI's avatar
Level 58

To implement user roles in Laravel, you can follow these best practices:

  1. Database Design: Create a roles table and a pivot table role_user to establish a many-to-many relationship between users and roles.

    // Migration for roles table
    Schema::create('roles', function (Blueprint $table) {
        $table->id();
        $table->string('name')->unique();
        $table->timestamps();
    });
    
    // Migration for role_user pivot table
    Schema::create('role_user', function (Blueprint $table) {
        $table->id();
        $table->foreignId('user_id')->constrained()->onDelete('cascade');
        $table->foreignId('role_id')->constrained()->onDelete('cascade');
        $table->timestamps();
    });
    
  2. Define Relationships: In your User model, define the relationship to roles.

    class User extends Authenticatable
    {
        public function roles()
        {
            return $this->belongsToMany(Role::class);
        }
    
        public function hasRole($role)
        {
            return $this->roles()->where('name', $role)->exists();
        }
    }
    
  3. Assign Roles: You can assign roles to users using the relationship.

    $user = User::find(1);
    $role = Role::where('name', 'admin')->first();
    $user->roles()->attach($role);
    
  4. Authorization: Use middleware to restrict access based on roles.

    • Create a middleware:

      php artisan make:middleware RoleMiddleware
      
    • Implement the middleware logic:

      public function handle($request, Closure $next, $role)
      {
          if (!auth()->check() || !auth()->user()->hasRole($role)) {
              abort(403, 'Unauthorized');
          }
      
          return $next($request);
      }
      
    • Register the middleware in app/Http/Kernel.php:

      protected $routeMiddleware = [
          // ...
          'role' => \App\Http\Middleware\RoleMiddleware::class,
      ];
      
  5. Apply Middleware to Routes: Use the middleware in your routes to protect them.

    Route::group(['middleware' => ['role:admin']], function () {
        Route::get('/admin', [AdminController::class, 'index']);
    });
    
  6. Policy and Gates: For more granular control, consider using Laravel's policies and gates.

    • Define a policy:

      php artisan make:policy UserPolicy
      
    • Implement the policy methods:

      public function viewAdminDashboard(User $user)
      {
          return $user->hasRole('admin');
      }
      
    • Register the policy in AuthServiceProvider:

      protected $policies = [
          User::class => UserPolicy::class,
      ];
      
    • Use the policy in controllers:

      $this->authorize('viewAdminDashboard', User::class);
      

By following these steps, you can effectively manage user roles and permissions in your Laravel application, ensuring that users can only perform actions specific to their roles.

Tray2's avatar

You create two tables roles and role_user the first containing all the different roles, and the other is a pivot table connection the role and the user together.

The you create a middleware/auth guard that you use for each of the actions you want to limit the access to.

You can then use the @can blade directive to determine if something should be displayed or not in the view, and you can use the middleware to prevent access to the routes you want to protect.

Snapey's avatar
Snapey
Best Answer
Level 122

if your users can be only one type, then the addition of a role column to the users table is sufficient. If a user can have more than one role then you need a pivot table.

Then it is a question of using gates to decide if a user can perform a certain action

https://laravel.com/docs/12.x/authorization#gates

martinbean's avatar

How can I properly authorize each user to perform only the actions specific to their role?

@aymanmsh This is what authorization is for.

Define roles. Then use middleware to determine what routes the authenticated user can access based on their role(s).

This topic has been asked about so many times on this forum alone, then I wrote my thoughts up in a blog post: https://martinbean.dev/blog/2021/07/29/simple-role-based-authentication-laravel/

Please or to participate in this conversation.