Laravel Roles, Permissions using Spatie
1.
composer create-project laravel/laravel example-app
2. setup mysql in .env file
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dbNAMEhere
DB_USERNAME=root
DB_PASSWORD=
3. install laravel breeze, or any other module that used for user authentication
4. Install the Spatie Package with the following command:
composer require spatie/laravel-permission
5. The service provider will automatically get registered. Or you may manually add the service provider in your config/app.php file:
'providers' => [
// ...
Spatie\Permission\PermissionServiceProvider::class,
];
6. publish the migration
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate
7. This package comes with RoleMiddleware, PermissionMiddleware and RoleOrPermissionMiddleware middleware. You can add them inside your app/Http/Kernel.php file to be able to use them through aliases.
// Note: Laravel 10+ uses $middlewareAliases = [
protected $middlewareAliases = [
// ...
'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
];
//if < laravel 10
protected $routeMiddleware = [
// other middleware...
'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
];
8. Add the necessary trait to your User model ( app/Models/User.php ) :
class User extends Authenticatable
{
use HasRoles;
9. CREATE ROUTES
Route::group(['middleware' => ['role:super-admin|admin']], function() {
Route::resource('permissions', App\Http\Controllers\PermissionController::class);
Route::get('permissions/{permissionId}/delete', [App\Http\Controllers\PermissionController::class, 'destroy']);
Route::resource('roles', App\Http\Controllers\RoleController::class);
Route::get('roles/{roleId}/delete', [App\Http\Controllers\RoleController::class, 'destroy']);
Route::get('roles/{roleId}/give-permissions', [App\Http\Controllers\RoleController::class, 'addPermissionToRole']);
Route::put('roles/{roleId}/give-permissions', [App\Http\Controllers\RoleController::class, 'givePermissionToRole']);
Route::resource('users', App\Http\Controllers\UserController::class);
Route::get('users/{userId}/delete', [App\Http\Controllers\UserController::class, 'destroy']);
});
10. Download controllers and views from here and paste into your projects
https://github.com/RizwanKMW/laravel-permission
11. create the seeder with the following command:
php artisan db:seed --class="UserRolePermissionSeeder"
12. RUN THE BELOW COMMADND AND access http://abc.com/roles
php artisan serve
EXPLAINATION:
1. HOW TO CREATE ROLES AND PERMISSIONS
$role = \Spatie\Permission\Models\Role::create(['name' => 'manager']);
$permission = \Spatie\Permission\Models\Permission::create(['name' => 'view users']);
2. Assign permissions to created roles
$roleis = \Spatie\Permission\Models\Role::findByName("manager"); //first find role
$roleis->givePermissionTo("view users"); //then give permission by name
$role->givePermissionTo($permission); //or give created permission previously step
$roleis->syncPermissions(['view user', 'delete user']); //delete all old permissions and assign new ones
3. Remove Roles and permissions
$roleis->revokePermissionTo('delete user'); //permission remove from role
$permission->removeRole($role); //remove role from permission
4. ASSIGN ROLE TO USER
$user = \App\Models\User::find(7);
/***Add roles,not remove existing roles. ***/
$user->assignRole('manager');
//$user->assignRole(['admin', 'editor']);
/*** Remove all roles, and assign new one's ***/
$user->syncRoles(['admin', 'editor']);
5. Setup routes to prevent user from access , only assigned role can access that routes
Route::group(['middleware' => ['role:super-admin|admin']], function() {
//only admin or super-admin can access these routes ie
Route::resource('users', App\Http\Controllers\UserController::class);
});
6. Prevent methods to unauthorized permissions
if user has "create posts" permissions only He/She can access create and store methods,
public function __construct()
{
$this->middleware('permission:create posts', ['only' => ['create', 'store']]);
}
7. if user has Roles Inside controllerMethods
$user = auth()->user(); // Get the authenticated user
if ($user->hasRole('admin')) {
echo "admin";
}
//FOR MULTIPLE ROLES CHECK
if ($user->hasAnyRole(['admin','user'])) {
echo "admin";
}
// TRY TO use to prevnet error "Call to a member function hasAnyRole() on null"
if(auth()->check() && auth()->user()->hasAnyRole(['admin'])){
echo " secured <3";
}
8. Check permissions inside controller Method
if ($user->can('delete posts')) {
echo "User can delete posts";
}
##### multiple permissions check
if ($user->can(['create posts', 'edit posts'])) { }
9. IN VIEWS, check if role have permission
@can('delete posts')
<div class="xd"></div>
@endcan
10 IN VIEWS, DISPLAY CURRENT ROLES
@if (Auth::check())
<p>Your Role: {{ Auth::user()->getRoleNames()->implode(', ') }}</p>
@endif
11. Show content if user have no permission
@if(auth()->user()->cannot('view_payment_stats'))
<p>I have no permission view_payment_stats, so I can see this, anyone that have this permission are not allowed to see this</p>
@else
<p>I have permission</p>
@endif
If sometime roles not work try below commands
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
php artisan permission:cache-reset
https://www.fundaofwebit.com/post/laravel-10-spatie-user-roles-and-permissions-tutorial