How to Create User Roles and Permissions in Laravel 8

When developing a Laravel 8 application, managing user roles and permissions is a critical part of any secure web platform. Whether you’re building an admin panel, a content management system (CMS), or a multi-user SaaS application, implementing proper role-based access control (RBAC) ensures that users only access features they’re authorized to use.

One of the most powerful and popular packages for managing roles and permissions in Laravel is the Spatie Laravel-Permission package. It’s easy to set up, integrates seamlessly with Laravel’s policies and gates, and allows developers to define flexible permission structures.

In this detailed tutorial, you’ll learn how to implement Spatie’s Laravel Permission package in a Laravel 8 application — step-by-step. We’ll cover installation, configuration, assigning roles and permissions, middleware protection, and more.

What Is the Spatie Laravel-Permission Package

[Spatie Laravel-Permission](https://spatie.be/docs/laravel-permission) is an open-source Laravel package that provides an expressive way to handle authorization via roles and permissions. It enables developers to:

– Assign multiple **roles** to users.
– Assign multiple **permissions** to roles or users directly.
– Use middleware to protect routes based on roles/permissions.
– Easily check user permissions in controllers or Blade views.
– Sync roles and permissions efficiently.

Step 1: Install the Package via Composer

To begin, navigate to your Laravel 8 project directory and run the following command to install the package:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
composer require spatie/laravel-permission
composer require spatie/laravel-permission
composer require spatie/laravel-permission

This command will download the package and add it to your project’s dependencies.

Step 2: Publish the Configuration and Migration Files

After installation, publish the configuration file and migrations:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

This command will publish:
– `config/permission.php`
– Migration files for `roles`, `permissions`, `model_has_roles`, `model_has_permissions`, and `role_has_permissions` tables.
These tables are essential for mapping users, roles, and permissions.

Step 3: Run the Migrations

Next, run the Laravel migration command to create the necessary database tables:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
php artisan migrate
php artisan migrate
php artisan migrate

You should now see the tables created in your database for handling roles and permissions.

Step 4: Add the `HasRoles` Trait to the User Model

To make your `User` model aware of roles and permissions, include the `HasRoles` trait:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
}
use Spatie\Permission\Traits\HasRoles; class User extends Authenticatable { use HasRoles; }
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
    use HasRoles;
}

This trait adds helpful methods such as `assignRole()`, `hasRole()`, `givePermissionTo()`, and others directly to your User model.

Step 5: Create Roles and Permissions in Laravel

You can create roles and permissions via database seeders, Laravel tinker, or directly in your application code.

Here’s a quick example using Eloquent:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
// Create permissions
Permission::create(['name' => 'edit articles']);
Permission::create(['name' => 'delete articles']);
// Create a role and assign permissions
$role = Role::create(['name' => 'editor']);
$role->givePermissionTo(['edit articles', 'delete articles']);
// Assign role to a user
$user = User::find(1);
$user->assignRole('editor');
use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; // Create permissions Permission::create(['name' => 'edit articles']); Permission::create(['name' => 'delete articles']); // Create a role and assign permissions $role = Role::create(['name' => 'editor']); $role->givePermissionTo(['edit articles', 'delete articles']); // Assign role to a user $user = User::find(1); $user->assignRole('editor');
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;

// Create permissions
Permission::create(['name' => 'edit articles']);
Permission::create(['name' => 'delete articles']);

// Create a role and assign permissions
$role = Role::create(['name' => 'editor']);
$role->givePermissionTo(['edit articles', 'delete articles']);

// Assign role to a user
$user = User::find(1);
$user->assignRole('editor');

You can also assign permissions directly to a user:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$user->givePermissionTo('edit articles');
$user->givePermissionTo('edit articles');
$user->givePermissionTo('edit articles');

This is especially useful for advanced user customization or admin overrides.

Step 6: Checking Roles and Permissions

The package provides intuitive methods to verify if a user has certain access:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$user->hasRole('editor'); // true or false
$user->can('edit articles'); // true or false
$user->hasPermissionTo('delete articles'); // true or false
$user->hasRole('editor'); // true or false $user->can('edit articles'); // true or false $user->hasPermissionTo('delete articles'); // true or false
$user->hasRole('editor'); // true or false
$user->can('edit articles'); // true or false
$user->hasPermissionTo('delete articles'); // true or false

These checks can be used in controllers, middleware, or Blade templates.

Step 7: Protect Routes with Middleware

You can easily protect routes using middleware provided by the package.
### Register Middleware (Laravel 8+ already includes them)
In `app/Http/Kernel.php`, verify or add:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class, 'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,

### Protecting Routes

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Route::get('/admin', function () {
// Only accessible by users with 'admin' role
})->middleware('role:admin');
Route::get('/edit', function () {
// Only accessible to users with 'edit articles' permission
})->middleware('permission:edit articles');
Route::get('/admin', function () { // Only accessible by users with 'admin' role })->middleware('role:admin'); Route::get('/edit', function () { // Only accessible to users with 'edit articles' permission })->middleware('permission:edit articles');
Route::get('/admin', function () {
    // Only accessible by users with 'admin' role
})->middleware('role:admin');

Route::get('/edit', function () {
    // Only accessible to users with 'edit articles' permission
})->middleware('permission:edit articles');

You can also protect route groups:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Route::middleware(['role:admin'])->group(function () {
Route::get('/dashboard', [AdminController::class, 'index']);
});
Route::middleware(['role:admin'])->group(function () { Route::get('/dashboard', [AdminController::class, 'index']); });
Route::middleware(['role:admin'])->group(function () {
    Route::get('/dashboard', [AdminController::class, 'index']);
});

Additional Tips and Best Practices

– **Use `syncRoles()` or `syncPermissions()`** to replace a user’s roles or permissions instead of adding duplicates.
– **Clear permission cache** when updating roles or permissions:
“`bash
php artisan permission:cache-reset
“`
– **Use Laravel Gates/Policies** alongside Spatie for complex access logic.
– **Create seeders** to define roles and permissions in development/staging environments.

Blade Directives for Roles and Permissions

You can use Blade directives to show or hide parts of your UI:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@role('admin')
@role('admin')
@role('admin')

You are an admin user.

@endrole @can(‘edit articles’) Edit @endcan

These are very handy for building dynamic menus or permission-based content display.

Testing User Roles and Permissions

When writing tests, you can use Laravel’s built-in testing functionality to ensure route protection works correctly.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public function test_editor_cannot_access_admin_dashboard()
{
$user = User::factory()->create()->assignRole('editor');
$response = $this->actingAs($user)->get('/admin');
$response->assertStatus(403);
}
public function test_editor_cannot_access_admin_dashboard() { $user = User::factory()->create()->assignRole('editor'); $response = $this->actingAs($user)->get('/admin'); $response->assertStatus(403); }
public function test_editor_cannot_access_admin_dashboard()
{
    $user = User::factory()->create()->assignRole('editor');
    $response = $this->actingAs($user)->get('/admin');
    $response->assertStatus(403);
}

This ensures unauthorized users are properly blocked.

Conclusion

The **Spatie Laravel-Permission** package provides a simple yet powerful way to manage user roles and permissions in a Laravel 8 application. Whether building a small blog or a large enterprise dashboard, controlling access is essential for security and user management.

Using this guide, you’ve learned:
– How to install and configure the Spatie package
– How to assign roles and permissions
– How to protect routes and check access
– How to integrate Blade and testing with roles

By integrating this system, you’ll ensure your application is secure, flexible, and scalable when it comes to user access control.

Read Also:

Understanding Cookies in PHP

How to Create a PHP Session

Also Visit:

https://inimisttech.com/

Leave a Reply