In this tutorial, we are going to earn how to set up multiple role based authentication in laravel. We are going to prevent the user from accessing the page based on their roles.
To demonstrate this example we are going to create some users with the role of admin and guest. We are also going to create a middleware and filter them through routes so that only the valid user can pass through.
If you are having confusion about what is middleware, it is the gateway between the routes and controller which you can prevent users to navigate to a certain page until some condition is satisfied. Still, confused? Don’t worry you will get more clear as soon as you hit the end of this page.
Let’s get started.
What are we going to do?
- Add a role field inside the user’s table and populate the dummy data with the roles.
- Create a role middleware and register it inside kernel.php.
- Writing a logic inside middleware to pass only the users with a specific role.
- Add this middleware into the routes.
- Write a function inside the controller to check if our middleware allowed only valid users to pass through.
How to setup Multiple Role Based Authentication in Laravel
Note:- We are going to use the laravel based authentication scaffolding to make it quick easy to generate a login system. Since in laravel 8 they don’t provide bundled app.css inside their js directory, we need Node Package Manager(NPM). Make sure you have installed nodeJS.
So, the first step will be to set up authentication scaffolding. You can just hit php artisan make:auth
if you are in laravel version up to 7. But for laravel 8 follow the steps below.
Setting up Authentication Scaffolding for Laravel8
First, we need to import laravel/ui package. Go to terminal and hit composer require laravel/ui
.
Hit php artisan ui bootstrap
& again php artisan ui boostrap --auth
to generate basic login and registration scaffolding.
Finally hit npm install
and npm run dev
. By now everything should be ready. Now let’s continue.
Step 1 – Adding New Role
To create a role inside user’s table, we need to add a new field called role inside the user’s migration file. I will add the role field with the integer which would be 0 for admin & 1 for normal users. Take a look at migration below.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->integer('role')->default(1); $table->rememberToken(); $table->timestamps(); }); } |
Hit php artisan migrate:refresh
to refresh the table with the new “role” field. Now we going to need some dummy users data. If you know how to generate dummy data using seeders and model factories go head and populate your users’ table.
If you are new to it, you can view my tutorial here on how to generate dummy data in laravel. For now, you can use this list of users and execute SQL Query directly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
INSERT INTO `users` (`id`, `name`, `email`, `email_verified_at`, `password`, `role`, `remember_token`, `created_at`, `updated_at`) VALUES (1, 'Isaiah Ryan', 'lehner.providenci@example.com', '2020-10-07 20:46:53', '$2y$10$POSK6f/Jm31/fg2SMBVrCuwr4Dvh5XiYYDr3WzvM6BBQ6LEZxgiEm', 0, 'OI8wYysdSBQIGXbtzX40JPb7BFjpRQg7XJMAUdFEEOHDj5Glp2bZy6esh5Vs', NULL, NULL), (2, 'Raphaelle Spinka', 'bernadine72@example.net', '2020-10-07 20:46:53', '$2y$10$1WnrGQUKX4KgF36s8rWa8umKub0kwE78lAHD3rBoMWfmTAjeHi4RG', 0, '1PJN7d2bep', NULL, NULL), (3, 'Zachariah Mosciski', 'lindgren.dorian@example.com', '2020-10-07 20:46:53', '$2y$10$GLyP6R1HbO5tWezwcs0igeoq5Kaigt6GB6f51eJ5lniCaZ/2rHGGu', 0, '5fpETR6xdl', NULL, NULL), (4, 'Emmie Kautzer IV', 'kayden.powlowski@example.net', '2020-10-07 20:46:53', '$2y$10$C9ldxGJXKe3WvDKlgqqMyevRXUSdPA4hetux2OK9rP5.TNYOlHvOm', 0, 'ObjnMCyjXo', NULL, NULL), (5, 'Madisyn Hessel', 'dibbert.anabel@example.com', '2020-10-07 20:46:53', '$2y$10$zuwgnKqZoughcyeP0ANOeea.h5t89TgW/riLcE3BeGv.H2Af8qsCi', 0, 'nXGMLjwbXt', NULL, NULL), (6, 'Theodore Prohaska', 'makenzie.hermann@example.org', '2020-10-07 20:46:54', '$2y$10$Kdj3J.2UcBOXPDSE0HGFye0oXhUtElTh.PvtyH17m1Xdu6yDL4uky', 0, 'sKZxJB2QR5', NULL, NULL), (7, 'Miss Luisa Hermiston', 'auer.bernice@example.net', '2020-10-07 20:46:54', '$2y$10$f1rDtwEQcUmz8mKVn3O/.uD7MFpDz5Yp.6g7qHgY06dAdIIHEPjku', 0, 'SWgwFrpW1i', NULL, NULL), (8, 'Monserrate McLaughlin', 'crystal.monahan@example.com', '2020-10-07 20:46:54', '$2y$10$oir8JHyXl/RBnQYxvzMFz.ipjboXeVBuLY7OzAgtn1ao4NbdDhNJa', 1, 'q0dd4QVr4An0m2KfR2TgfQzbACDHJ6LQWmu5kyc3nqIKex9RXZCkrVAnqTUU', NULL, NULL), (9, 'Elias McCullough', 'farrell.newton@example.org', '2020-10-07 20:46:54', '$2y$10$hauAT7MCXJpHHO.b1iRafOEAMPgSqVM2Rfi1zca77mRTcbJZrr9sG', 0, 'WKzyku6Kb8', NULL, NULL), (10, 'Nash Heathcote', 'wilmer86@example.org', '2020-10-07 20:46:54', '$2y$10$OR0/j2hVW/om80v37cKfhegxHxNHsu0Pi9dZUpfhonVZGyQH6ypAW', 0, '6CHYFnqVrT', NULL, NULL), (11, 'Mr. Abelardo Lang I', 'loraine.kling@example.net', '2020-10-07 20:46:54', '$2y$10$6VDRIMrUtlq1J7DxyRmSTeaNE4t8PeX5jq7EOjHQC7gl.twFCpvSe', 0, 'cXymAenmO6', NULL, NULL), (12, 'Elyssa Russel', 'huels.alisha@example.net', '2020-10-07 20:46:54', '$2y$10$65nlXRlL7pdHHHYL/q5KTeCbSE0g/GbGFEDKS00XftQ0zGF17ZVmW', 0, 'cXqE0LHRuZ', NULL, NULL), (13, 'Zelda Mosciski', 'wolff.constantin@example.net', '2020-10-07 20:46:54', '$2y$10$SMSrBV8FWfEiyITfXnSRT.3xgWbUgatAfZGgA08YM6Vde8xAbAZLO', 0, 'vf2bQHMY9t', NULL, NULL), (14, 'Terry Kuvalis', 'lyla.sporer@example.net', '2020-10-07 20:46:54', '$2y$10$jVkiQuheC80bW9ltkY9xEuZ2Pe3sBAktrd6KKy7rY99BtLjjs39ZO', 1, '4GiRZ8FIwi', NULL, NULL), (15, 'Jermain Skiles', 'monroe16@example.com', '2020-10-07 20:46:54', '$2y$10$CPOO6DJf3uS4622Xrw7e8eLN3BkrggIUSeyeKqctgufNrcCBtwAlu', 0, 'fohjlnC2gg', NULL, NULL), (16, 'Jana Durgan', 'frankie.collins@example.net', '2020-10-07 20:46:54', '$2y$10$ZqCiGRHo5MLOJtfgJ3sutOkx57apu4A8l8P261TDY5P/edu3LrvBi', 1, 'r4usG71CoC', NULL, NULL), (17, 'Ethelyn Balistreri', 'hilpert.monserrate@example.com', '2020-10-07 20:46:54', '$2y$10$2GYZ5N/pmnpRNRLDl3XhxOdPtcDEXzQw/fk9NuuomfDFYxhXvEbl6', 0, 'rD0FBca1B7', NULL, NULL), (18, 'Ms. Mazie Hansen', 'bkrajcik@example.com', '2020-10-07 20:46:55', '$2y$10$YWWLsQqCy.O/9Ln9hZ3P/uz7tMzKmhG6BFrWSYZB9SVWMUhMvjYIy', 1, 'cugWLDZssq', NULL, NULL), (19, 'Marcel Flatley', 'iyost@example.com', '2020-10-07 20:46:55', '$2y$10$hE.PUdVSiR8nw0d7TwP1aOIlNLKz5IS5mBeFIGs/nkSog.d1JGsoq', 1, 'JrtDpN6610', NULL, NULL), (20, 'Darion Barton', 'pcremin@example.net', '2020-10-07 20:46:55', '$2y$10$jLys/4CyW.qkUAJGqByee.pvoQHy8iab6PEAqAgHhv1uzPVAYse0S', 1, 'pHZWsj7n6S', NULL, NULL); |
The default password for all these users are password@123
Step 2: Creating a Role Middleware and Register in Kernel
Create a new middleware called “Role” by typing php artisan make:middleware Role
in your terminal.
Open kernel.php
from app/Http
and register role in $routeMiddleware
array.
1 2 3 4 |
protected $routeMiddleware = [ .... 'role' => \App\Http\Middleware\Role::class ]; |
Step3: Configuring Authorization in Middleware.
In this step, we are going to configure middleware in such a way that if someone is using this middleware will allow admin to pass through.
We will validate the user role and allow only the user with the role admin to pass through this middleware.
Open Role.php
from app/Http/Middleware
and paste the code below.
1 2 3 4 5 6 7 |
public function handle(Request $request, Closure $next) { if (Auth::user()->role == 0) { // if the current role is Administrator return $next($request); } abort(403, "Cannot access to restricted page"); } |
Finally, now we have to use it on any routes we want the only admin to pass through. Open routes/web.php
and write a new route using this middleware. Use the reference code below.
1 |
Route::get('/restricted', [App\Http\Controllers\HomeController::class, 'restricted'])->middleware(['role']); |
HomeController.php
1 2 3 |
public function restricted() { return "You are admin..!!"; } |
Now hit php artisan serve
and login through any of the users with a guest role (=1). You will be redirected to the page below.
If you logged in with the role 0 (admin). You will directly get pass through middleware with a message returned through your controller restricted function.
This will well handle even if you add more roles and you just need to check the role adding an or condition in your else statement as below.
1 2 3 4 5 |
if (Auth::user()->role == 0 || Auth::user()->role == 1 || Auth::user()->role == 2) { // if the current role is Administrator return $next($request); } |
This works. But it may not be as practical as it used to be in using middleware. Another way is you can pass parameters into the middleware directly through routes like below.
1 |
Route::get('/restricted', [App\Http\Controllers\HomeController::class, 'restricted'])->middleware(['role:0,1']); |
You can pass anything in the middleware and it will be accessible through the handle() function so that you can use it like below.
1 2 3 4 5 6 7 8 9 |
public function handle(Request $request, Closure $next, $admin, $guest) { // where $admin= 0 & $guest = 1 if (Auth::user()->role == $admin) { // if the current role is Administrator return $next($request); } else if (Auth::user()->role === $guest) { abort(403, "Cannot access to restricted page"); } } |
I hope this solves laravel role based authentication which can handle multiple user types. If you have any problem regarding it. You can contact us via the contact form on our website.
Dhruvi says
even after I login with role 0(admin) it does not show the message “You are an admin..!!!”.i.e. it does not pass through the middleware.
SNK says
First you need to check if the role you are getting is currently 0 or 1,
Next, make sure you have done $next($request); because it will not pass through it it isn’t there.
If this doesn’t work upload it in GitHub or contact me via email or contact form. We will sort out in a chat.