Using roles and permissions in Laravel can seem daunting at first. But when you break it down step by step its actually a very simple process.
In this example we are going to create 2 roles and 4 permissions.
We will then assign these permissions to the relevant roles. The 'admin' role will have all 4 permissions, while the 'standard' role will only have the 'read articles' role. We will then assign the roles to users within our application. Finally we will look at how to display content within our application based on the permissions held by the currently authenticated user. It sounds like a lot but it's very simple when you break it down!

The first thing we need to do is install the Spatie Permission package. Run the following command in the root of your Laravel project:
composer require spatie/laravel-permission
Now we need to publish the migration and config file. Run the following command:
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
Now we need to run the migration. Run the following artisan command:
php artisan migrate
We now need to add a the HasRoles trait to our User model. Open your User.php file and make sure it includes the following:
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
// ...
}
The Spatie package is now setup and ready to use. Now we need to actually create the roles and permissions that we want to use.
In this example we are going to use a seeder to create our roles and permissions. This is useful in some cases and not so useful in others. This method will allow us to create the roles and permissions for our application when we run our seeder command, but it won't help us if we need to manage the roles and permissions. If you want to create roles and permissions from an admin page within your application then you can still use the methods that I am going to show you. The difference will be that you will need to use them in a controller. But lets look at how to create them using a seeder.
Run the following command to create your seeder.
php artisan make:seeder --class=RolesSeeder
You should now have the file RolesSeeder.php in your seeders folder (found at project_root/database/seeders/RolesSeeder.php). Open your newly created RolesSeeder.php file. Add the following to the top of the file:
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
// ...
We are now able to create our roles and permissions.
Look at your RolesSeeder.php file. You will notice there is a function named public function run(). This is where we are going to include all the logic for creating our roles and permissions, and assigning our permissions to our roles. Now we are going to write the code that will create our 'admin' and 'standard' roles when we run our seeder. Add the following to the 'run' function:
public function run()
{
$role_admin = Role::create(['name' => 'admin']);
$role_standard = Role::create(['name' => 'standard']);
// we will add more to this in a second
}
Now we need to write the code that will create our permissions. Again, add to the 'run' function:
public function run()
{
$role_admin = Role::create(['name' => 'admin']);
$role_standard = Role::create(['name' => 'standard']);
$permission_read = Permission::create(['name' => 'read articles']);
$permission_edit = Permission::create(['name' => 'edit articles']);
$permission_write = Permission::create(['name' => 'write articles']);
$permission_delete = Permission::create(['name' => 'delete articles']);
// we will add more to this in a second
}
Now we need to assign the permissions to the relevant roles. In our example we are going to give the 'admin' role all 4 permissions, and give the 'standard' role the permission to 'read articles' only. Go back to the RolesSeeder.php file and add to the 'run' function:
public function run()
{
$role_admin = Role::create(['name' => 'admin']);
$role_standard = Role::create(['name' => 'standard']);
$permission_read = Permission::create(['name' => 'read articles']);
$permission_edit = Permission::create(['name' => 'edit articles']);
$permission_write = Permission::create(['name' => 'write articles']);
$permission_delete = Permission::create(['name' => 'delete articles']);
$permissions_admin = [$permission_read, $permission_edit, $permission_write, $permission_delete];
$role_admin->syncPermissions($permissions_admin);
$role_standard->givePermissionTo($permission_read);
}
We are not going to run this seeder just yet, but when we do it will create our roles, create our permissions, and assign the permissions to the roles. We now need to look at how to assign the roles to users. There are 2 ways in which we are going to do this. By assigning newly created users that sign up to our website via the registration form a role when they sign up, and by assigning our seeded users a role when they are created. Lets first look at assigning roles to our seeded users.
If you haven't already, create a user seeder. We are now going to edit the 'run' function in our UserSeeder.php file. Add the following:
public function run()
{
//
$users = [
[
'name' => 'Admin',
'email' => 'admin@codingoblin.com',
'password' => 'password',
'role' => 'admin',
],
[
'name' => 'John',
'email' => 'john@codingoblin.com',
'password' => 'password2',
'role' => 'standard',
]
];
foreach($users as $user) {
$created_user = User::create([
'name' => $user['name'],
'email' => $user['email'],
'password' => Hash::make($user['password']),
]);
$created_user->assignRole($user['role']);
}
}
Now go to your DatabaseSeeder.php file and add the following:
namespace Database\Seeders;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Database\Seeders\UserSeeder;
use Database\Seeders\RolesSeeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call([
RolesSeeder::class,
UserSeeder::class,
]);
}
}
Now we just need to run our seeders. To just run our seeders run the following command:
php artisan db:seed
This probably won't be much use to us as we have most likely already previously run this command and therefore created our users already. If you wish to drop all tables in your database, start again fresh and run the seeders, run the following command instead:
php artisan migrate:fresh --seed
You should now have your roles and permissions created, permissions assigned to relevant roles, users created, roles assigned to relevant users.
We have seen how to assign roles to users using seeders, but now we need to look at assigning roles to the users who sign up to our website through our registration form. The good news is this is really quick and easy. In our example, we will assign new users the role 'standard'. Open your CreateNewUser.php file found at your_project/app/Actions/Fortify/CreateNewUser.php. Amend the 'create' function so that it looks like this:
public function create(array $input)
{
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => $this->passwordRules(),
'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['accepted', 'required'] : '',
])->validate();
$created_user = User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]);
$created_user->assignRole('standard');
return $created_user;
}
And that's it. I told you it was simple. Now when a new user registers they will automatically be assigned the 'standard' role.
We are now in a position where we are able to make use of our roles and permissions to show and hide content depending on the role of the user. To do this, we are going to make use of props. We will send the roles and permissions that the user possesses along with each request. This means we can check a user has permission to view something before we show it to them.
By default, out Laravel Jetstream application sends certain page props with every request. One of these is an object containing lots of information about the currently authenticated user. We are going to append the roles and permissions held by the user to this object, so we can also access this in our page views!
To add the roles and permissions to the page props, we need to add a couple of lines of code to the HandleInertiaRequests Middleware. You can find this file at your_project/app/Http/Middleware/HandleInertiaRequests.php. Open this file and add the following to the 'share' function:
public function share(Request $request): array
{
return array_merge(parent::share($request), [
//
'user.roles' => $request->user() ? $request->user()->roles->pluck('name') : [],
'user.permissions' => $request->user() ? $request->user()->getPermissionsViaRoles()->pluck('name') : [],
]);
}
Now, whenever an authenticated (logged in) user accesses a page on our website, we can see what roles and permissions they have by looking in the $page.props. Lets see that in action!
We are now in a position where we can access the authenticated user's roles and permissions in our page views (our Vue.js files). To see this in action, go to a page within your application (we will be using the default dashboard page that comes with Laravel Jetstream, and will be editing this file - your_project/resources/js/Components/Welcome.vue. Add this code to your page template:
Save the file and go to the page in the browser (make sure you are using a logged in user with a role). You should see the following on your page:

Notice that we can see arrays containing the user's roles and permissions.
We are now in a position to actually use the roles and permissions to hide and show content on the page. To demonstrate this we will create 4 buttons on our page. You can do this on any page you like but if you are following along we will use the same file - your_project/resources/js/Components/Welcome.vue. Open Welcome.vue, remove everything between the template tags replace it with this:
Above we have 4 buttons. Each button is wrapped in a div that is shown conditionally. Each if statement is saying, if the permission name is found within the permission array that is passed to the page as a prop within the user object prop, then show the button. If you are logged in as the 'admin' role, you will see all 4 buttons. If you are logged in as the 'standard' role you will just see the 'read articles' button. You have now successfully implemented roles and permission in your Laravel Jetstream (Inertiajs) application on the frontend! Congratulations. But what about protecting resources on the backend? Lets look at how to do this!
You're going to have to deploy at some point. When you do, I strongly recommend Cloudways hosting. I have had a great experience with them. Great for Laravel in particular.
ReplyGuy an idiots first impression
Are you looking for a way to automate your marketing efforts? Do you like new, and innovative technology? Well, maybe you will enjoy using ReplyGuy. I gave it a go to see what all the fuss if about
Sam Ovens, the brains behind skool.com
Sam Ovens is the man behind skool.com. Let’s take a look at his background and who the guy is. Is he too cool for skool?