As the systems you build become more sophisticated you will find it necessary to implement more elaborate security based on the different roles the users of your system are acting in. In the tennisclub example we have been using there could reasonably be a number of roles including, System Admin, Club Secretary, Club Coach and Club Member. A system administrator is generally a super user who can access all parts of the system, it's always necessary to have one super user to access all functional componenets in case some aspect of the system becomes blocked or broken. A club secretary might reasonably be expected to assign members into different roles - for example if a new coach was appointed they could assign them into that role. A coach might get certain privileges to block book courts or delete bookings where as ordinary members might only be able to book two hours at at time. No matter what the system, there will be users, roles and permissions.
Laravel, as we know, has built in user-registration and authorisation. It also provides all the mechanism to programatically lock down aspects of your application using system of "gates" and "guards". While this is useful and robust it involves writing a lot of code and does not save information regarding roles and permissions in the database. This means role assignment and permission assignment to roles requires a programmer. This is not ideal as, for many systems, these features would be expected to regularly managed by system admins without a code change.
Luckily there are a number of laravel packages to address this. By far the most popular of these is maintatined by a Belgian WebDesign Company called Spatie and is called Laravel-Permission. There is good documentation and support available for this package and a good well established community of users. This makes it the best bet as a proven established security package. The following posts will desribe how to:
- install the Spatie - Laravel Permission Package on your system
- How to build a Simple User interface for the Spatie packages allowing non-programmer users to assign roles and permissions
- How to lock down the application so that only users acting in certain roles can gain access to certain routes
Installing Spatie - Laravel-permission
To install laravel permission using composer in the root folder of your application as follows
php composer.phar require spatie/laravel-permission
Next, to add this to the list of laravel service providers, edit the file config/app.php and add the following line of code to the bottom of the list of service providers in the 'providers' array
Spatie\Permission\PermissionServiceProvider::class,
The line should go into the list as follows
Next you have to create and publish the migration file. The migration file is the one which will create the database tables assoicated with maintaining the roles and permissions and the relationships between the users roles and permissions. We'll talk about these table a bit more in the next post. For now, we create the migration file by publishing it with the following line
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
This will create the migration file as follows.
Before proceeding you should clear your application cache by removing any caching of configuration as follows
php artisan config:clear
Before we can run the migration to create the database tables, there are some slight adjustments we have to make. Firstly, in Laravel 5.4 the charater set used was switched to utf8mb4. This uses longer length fields and keys to, among other things, support emojis. One issue with this is that it does not play nicely with older versions of MySQL or versions using MariaDB as and engine. To get around this problem we need to modify app/Providers/appServiceProvider.php and include the following modifications which will reset the default String Length. Add the following line at the top of the file with the use clauses
use Illuminate\Support\Facades\Schema;
Add this line to the boot function
Schema::defaultStringLength(191);
It's possible you have already made these changes in an early example/post. If so you can proceed to the migration. Make sure the appServiceProvider.php file looks as follows
User HasRoles
To all the User class which ships with Laravel to use Spatie's roles we need to make some slight modifications to that class. Edit the file app\Models\User.php and add the following line at the top to allow the User to use the Spatie HasRoles Trait from its namespace
use Spatie\Permission\Traits\HasRoles;
Now add two other lines two instruct the class to use that trait and to set the guard_name to 'web' (guard names are discussed in more detail later)
use HasRoles;
protected $guard_name = 'web';
These lines appear as follows in the app\User.php class
Next, we need to make a slight modification to the migration file which was published by Spatie before we run the migration. We need to make it so that the tables created by the migrations for the roles and permissions tables set the field for guard_name to be both nullable and have a default value of 'web'. The reason for this will be explained in the next section. To do this, open up the file in the database folder which looks like 2021_02_10_170535_create_permission_tables.php. Your date and timestamp at the beginning of the filename will be different to the one mentioned here - don't worry about this. Add
->nullable()->default('web');
To the ends of the fields settings for gaurd_name in both the roles and permissions tables.
This should look like the following
You are now clear to run the migration which will create the database tables which will support Spatie - Laravel-permission. To do this run the command:
php artisan migrate
This will produce the following result
Now if you refresh your database under your preferred MySQL client (mine is HeidiSQL) you will notice a range of new tables in your application
You now have Spatie Laravel-permission installed and ready to use. In the next post we'll see how to create a simple UI to access these database tables and create new roles and permissions and assign them to appropriate users.