DEV Community

Cover image for Master Role-Based Access Control with Laravel Permission Manager
Hossein Hezami
Hossein Hezami

Posted on

Master Role-Based Access Control with Laravel Permission Manager

Building a secure, scalable Laravel application often requires a robust permission management system. Enter Laravel Permission Manager, a powerful package designed to streamline role-based access control (RBAC) with a flexible, feature-rich API. Whether you're securing routes, managing roles, or integrating permissions into your Blade templates, this package has you covered. In this post, I'll walk you through its installation, configuration, and usage to help you implement a bulletproof RBAC system in your Laravel app.


Why Laravel Permission Manager?

The Laravel Permission Manager package, developed by Hossein Hezami, offers a comprehensive solution for managing roles and permissions in Laravel applications. Here’s what makes it stand out:

  • Role-Based Access Control (RBAC): Assign multiple roles to users and permissions to roles.
  • Wildcard Permissions: Support for flexible route matching (e.g., admin.*, *admin*).
  • Blade Directives: Easily check roles and permissions in templates with @hasRole and @hasPermission.
  • Artisan Commands: Manage roles and permissions from the command line.
  • Facade Methods: Programmatically handle roles and permissions with a fluent API.
  • Middleware Support: Protect routes with role or permission checks.
  • Caching: Boost performance with permission caching.
  • Multi-Guard Support: Works seamlessly with Laravel’s authentication guards.
  • Export/Import: Save and restore roles/permissions as JSON.

Ready to get started? Let’s dive into the setup and usage.


Installation

Installing Laravel Permission Manager is straightforward with Composer. Follow these steps to integrate it into your Laravel project:

  1. Install the Package Run the following command to install the package:
   composer require hosseinhezami/laravel-permission-manager
Enter fullscreen mode Exit fullscreen mode
  1. Register the Service Provider (Optional) If Laravel’s package auto-discovery is disabled, add the service provider and facade to config/app.php:
   'providers' => [
       // ...
       HosseinHezami\PermissionManager\PermissionManagerServiceProvider::class,
   ],
   'aliases' => [
       // ...
       'PermissionManager' => HosseinHezami\PermissionManager\Facades\PermissionManager::class,
   ],
Enter fullscreen mode Exit fullscreen mode
  1. Publish Configuration and Migrations Publish the configuration file and migrations to set up the package:
   php artisan vendor:publish --provider="HosseinHezami\PermissionManager\PermissionManagerServiceProvider" --tag="config"
   php artisan vendor:publish --provider="HosseinHezami\PermissionManager\PermissionManagerServiceProvider" --tag="migrations"
Enter fullscreen mode Exit fullscreen mode
  1. Run Migrations Create the necessary database tables for roles and permissions:
   php artisan migrate
Enter fullscreen mode Exit fullscreen mode
  1. Add the Permission Trait Add the PermissionTrait to your User model:
   namespace App\Models;

   use HosseinHezami\PermissionManager\Traits\PermissionTrait;
   use Illuminate\Foundation\Auth\User as Authenticatable;

   class User extends Authenticatable
   {
       use PermissionTrait;
   }
Enter fullscreen mode Exit fullscreen mode
  1. Run the Install Command For a streamlined setup, use the Artisan install command. Here are some variations:
   # Basic installation
   php artisan permission-manager:install

   # Install and run migrations
   php artisan permission-manager:install --migrate

   # Install, run migrations, and overwrite existing files
   php artisan permission-manager:install --migrate --force

   # Install with a custom User model path
   php artisan permission-manager:install --user-model=/path/to/User.php
Enter fullscreen mode Exit fullscreen mode

Configuration

After publishing the configuration, you can customize the package in config/permission-manager.php. Here’s a sample configuration:

return [
    'models' => [
        'role' => \HosseinHezami\PermissionManager\Models\Role::class,
        'permission' => \HosseinHezami\PermissionManager\Models\Permission::class,
        'user' => \App\Models\User::class,
    ],
    'tables' => [
        'roles' => 'roles',
        'permissions' => 'permissions',
        'role_permissions' => 'role_permissions',
        'user_roles' => 'user_roles',
    ],
    'cache_duration' => 60, // Cache permissions for 60 minutes
    'log_denials' => false, // Log permission/role denials
    'wildcards' => true, // Enable wildcard support
];
Enter fullscreen mode Exit fullscreen mode

This file lets you tweak model classes, table names, caching duration, and wildcard support to suit your application’s needs.


Database Migrations

The package creates four tables to manage roles and permissions:

  • roles: Stores role details (name, slug, description).
  • permissions: Stores permission routes (e.g., users.edit).
  • role_permissions: Links roles to permissions.
  • user_roles: Links users to roles.

The migrations are automatically published when you run the vendor:publish command for the migrations tag.


Usage

Let’s explore how to leverage Laravel Permission Manager in your application.

1. Blade Directives

Control access in your Blade templates with intuitive directives:

@hasRole('admin')
    <p>Welcome, Admin!</p>
@endhasRole

@hasPermission('users.edit')
    <a href="/users/edit">Edit User</a>
@endhasPermission
Enter fullscreen mode Exit fullscreen mode

These directives make it easy to show or hide content based on roles or permissions.

2. Middleware

Protect routes with middleware for roles or permissions:

Route::get('/admin', [AdminController::class, 'index'])
    ->middleware('pm:role:admin|manager');

Route::get('/posts', [PostController::class, 'create'])
    ->middleware('pm:permission:posts|post.create');
Enter fullscreen mode Exit fullscreen mode

The pm middleware ensures only users with the specified roles or permissions can access the route.

3. Artisan Commands

Manage roles and permissions directly from the terminal:

# List roles and permissions
php artisan roles:list
php artisan permissions:list

# Create a role
php artisan role:create admin "Administrator" "Has full system access"

# Update a role
php artisan role:update admin --name="Super Admin" --description="Updated description"

# Delete a role
php artisan role:delete admin

# Create permissions
php artisan permission:create "users.*"
php artisan permission:create "users.create,users.edit"

# Sync routes with permissions
php artisan permission:sync-routes

# Assign/revoke permissions to a role
php artisan role:assign-permission admin "users.*"
php artisan role:revoke-permission admin "users.edit"

# Assign/revoke roles to a user
php artisan user:assign-role 1 admin
php artisan user:revoke-role 1 admin

# Export/import roles
php artisan role:export roles.json
php artisan role:import roles.json
Enter fullscreen mode Exit fullscreen mode

These commands make it easy to manage your RBAC system without writing code.

4. Facade Methods

For programmatic control, use the PermissionManager facade:

use HosseinHezami\PermissionManager\Facades\PermissionManager;

// Create a role
PermissionManager::roles()->create([
    'slug' => 'admin',
    'name' => 'Administrator',
    'description' => 'Has full system access'
]);

// Assign permissions to a role
PermissionManager::role('admin')->assignPermission('users.edit');

// Assign a role to a user
PermissionManager::user(1)->assignRole('admin');

// Check permissions
$hasPermission = PermissionManager::user(1)->hasPermission('users.edit');
Enter fullscreen mode Exit fullscreen mode

5. Wildcard Permissions

Wildcard permissions add flexibility to route matching:

// Match all routes starting with 'admin'
PermissionManager::permissions()->create('admin.*');

// Match all routes containing 'admin'
PermissionManager::permissions()->create('*admin*');
Enter fullscreen mode Exit fullscreen mode

6. Trait Methods

The PermissionTrait adds convenient methods to your User model:

$user = User::find(1);

// Assign a role
$user->assignRole('admin');

// Check permissions
if ($user->hasPermission('users.edit')) {
    // Allow edit action
}
Enter fullscreen mode Exit fullscreen mode

Best Practices

  • Use Descriptive Slugs: Choose clear, meaningful slugs for roles and permissions (e.g., users.edit instead of edit).
  • Leverage Wildcards: Group related routes with wildcards (e.g., users.* for all user-related actions).
  • Sync Routes Regularly: Run php artisan permission:sync-routes to keep permissions aligned with your routes.
  • Enable Caching: Set a reasonable cache_duration in production to improve performance.
  • Handle Exceptions: Use the package’s custom exceptions (e.g., UnauthorizedException) for robust error handling.

Conclusion

The Laravel Permission Manager package is a game-changer for developers building secure Laravel applications. Its intuitive API, comprehensive Artisan commands, and flexible features like wildcard permissions and Blade directives make it a must-have for implementing RBAC. Whether you’re managing a small app or a large-scale system, this package simplifies access control without compromising on power.

Check out the official documentation for more details, and feel free to contribute via the GitHub repository. Got questions? Reach out to the maintainer at hossein.hezami@gmail.com.

What’s your favorite way to manage permissions in Laravel? Share your thoughts in the comments!

Top comments (0)