Streamline Role-Based Access Control with Spatie Laravel Permission

In today's application development landscape, Role-Based Access Control (RBAC) has become a standard feature in most modern applications. If you're a Laravel developer, implementing RBAC is straightforward, thanks to the Spatie Permission package. This powerful package simplifies the process, making it easier to manage roles and permissions in your Laravel projects.

The Spatie Permission package enables you to efficiently manage user permissions, both in your database and directly within your application's UI.

Installation steps:

To get started, install the Spatie Permission package directly into your Laravel project using Composer

 composer require spatie/laravel-permission

The service provider will automatically be registered. However, if you wish to register it manually, you can add it to the providers array in your config/app.php file

'providers' => [
    // ...
    Spatie\Permission\PermissionServiceProvider::class,
];

Publish the Configuration and Migration Files

Run the following command to publish the package's configuration and migration files

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

This will create:

  • A configuration file at config/permission.php.

  • Migration files for the required database tables.

If a config/permission.php file already exists, rename or remove it before publishing.

Once installed, you'll find the migration files in the database/migrations directory. These files help set up the necessary database tables for managing roles and permissions.

Below, you can also see the Entity-Relationship Diagram (ERD) for better understanding.

Run the Migrations

After configuring the package, run the migrations to create the necessary database tables.

php artisan migrate

Update the User Model

To enable role and permission management, add the HasRoles trait to your User model.

use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable

    use HasRole;

Before using the package directly in your code, you need to populate the roles and permissions in the appropriate database tables.

Here's an example

it's often better to add roles and permissions during migration since the necessary tables are already created as part of the application setup. This ensures everything is integrated seamlessly from the start.

Create a permission seeder to populate all the necessary permissions for your application. This ensures that your permissions are systematically added and easily manageable.

 public function run(): void
    {
        $permissions = [
            [
                "name"=> "documents.create"
            ],
            [
                "name"=> "documents.update"
            ],
            [
                "name"=> "documents.view"
            ],
            [
                "name"=> "documents.delete"
            ],

        ];

        //iterate all permissions and store into the permission table
        foreach ($permissions as $key => $value) {
            $permission = new Permission;
            $permission->name = $value['name'];
            $permission->save();
        }
    }

Next, create default roles and assign the appropriate permissions to each role. For example, you can create an admin role, retrieve the full list of permissions, and assign them to the admin role. Below is an example.

This is how you can assign a specific permission to the appropriate role using the .

//assign a create a permission to the current role
$role->givePermissionTo('create');

Using givePermissionTo() in Spatie Laravel Permission

The givePermissionTo() method in the Spatie Laravel Permission package is a powerful tool for managing permissions. It allows you to grant specific permissions to roles or users with ease, ensuring that your application’s access control aligns precisely with your requirements.

Example Usage

Here’s how you can use the givePermissionTo() method to assign permissions to a role.

use Spatie\Permission\Models\Role;

 public function run(): void
    {
        // create a Admin role
        $role = new Role;
        $role->name = 'Admin';
        $role->save();

        //Retrive all permissions
        $permissions = Permission::get();
        foreach ($permissions as $key => $permission) {
            // Assign all permission to the role
            $role->givePermissionTo($permission->name);
        }
    }

Alright, we’ve now created the permissions, defined roles, and assigned permissions to the admin role.

The next step is to create a new user and include it in your user seeder. This helps prepopulate your database with a default user, ideal for testing or administrative tasks.

Finally, assign the role to the user using the below assignRole() spatie method.

$user->assignRole('admin');

Understanding assignRole() in Spatie Laravel Permission

The assignRole() method provided by the Spatie Laravel Permission package simplifies the process of assigning roles to users. It not only establishes the relationship between the user and the role but also automatically associates all permissions linked to that role with the user. This means you don't need to manually handle the underlying relationships or assign permissions individually.

Example Usage

You can integrate the assignRole() method into your user creation logic or a dedicated role assignment module. Here's a sample code for better understanding.

 use App\Models\User;

$user = User::find(1); // Replace with the desired user ID
$user->assignRole('Admin'); // Assign the existing 'Admin' role to the user

now the role and appropriate permissions for the role created and assign it to the

You can now check your database. The first table to review is the Spatie permissions table. As shown, all document-related permissions have been successfully created and added to this table.

Below is an example for reference

Next, we created a role called admin. You can verify this by checking the Spatie roles table, where the role has been successfully created.

Using the givePermissionTo() method, we assigned permissions to the created role. You can verify this by checking the Spatie role_has_permissions table, where the assigned permissions are linked to the appropriate role.

By comparing the permissions table and the roles table, you can confirm that the permissions have been correctly assigned to the specified role in the role_has_permissions table.

Finally, we assigned the role to a user using the assignRole() method. You can verify this by checking the model_has_roles table, where you will find the role assigned to the corresponding user model ID.

In the example below, the role with ID 1 (admin) has been successfully assigned to the user with model ID 1.

That’s perfect! Now, let’s move on to the UI part and explore how to use these permissions in the appropriate places.

Using Permissions in Blade Templates

Blade is Laravel’s UI templating engine. Below is an example of how you can restrict access to a UI module or feature based on specific roles and permissions

This approach allows you to directly assign roles and permissions to UI features in a Laravel Blade template

Using Permissions with Inertia and React

In Laravel, you can seamlessly integrate React components using Inertia. Below is an example of how to use it.

Here, we import auth using Inertia’s usePage hook to access the current user’s permissions. You can then conditionally render components based on the assigned permissions.

Using Permissions Directly in React JSX

Now can directly use the created permissions in your React JSX as shown below.

This approach ensures that the component or content is only rendered for users who have the specified permission.

🚀 Thank you for reading this blog!

In this post, we explored how to set up and manage Role-Based Access Control (RBAC) using the Spatie Permission package in Laravel. We covered essential steps such as creating roles, assigning permissions, and integrating them into both Blade templates and React components with Inertia. By leveraging these tools, you can implement secure, scalable, and efficient access management in your Laravel applications.

Next Steps

To further enhance your RBAC implementation, consider the following:

  • Explore Middleware: Protect routes and resources by leveraging roles and permissions via middleware.

  • Customize Unauthorized Access: Tailor error messages or redirects for users lacking the required permissions.

  • Optimize Performance: Implement caching for permissions, especially in larger applications, to improve performance.

  • Audit Permission Changes: Integrate advanced auditing mechanisms to track changes in roles and permissions for better accountability.

If you found this tutorial helpful, don't forget to share it! Have questions, feedback, or suggestions for improving this implementation. Let’s connect in the comments below.