Set-up role based access control in Laravel (Updated 2019)

Set-up role based access control in Laravel (Updated 2019)

Editor’s Note: This post was initially published for older versions of Laravel and has been updated to work with the current version ( v5.8+).

Many a time in a web application, you will need to protect specific resources from being accessed by all of your users. While an authentication system ensures that only authorised users can access your application, but implementing precise role-based access control is sometimes necessary. Let me show you how you can implement role-based access control in Laravel.

We will not be using any external packages and use Laravel Middlewares to implement this. We will be applying access control for three roles, namely Admin, Agent, and Customer for the User model provided by Laravel.

Set up migrations:

  • Add a new role column to our existing user migration:

     
  • Run the migrations to generate the tables:

    Note: If you have already created the tables before, you may need to run php artisan migrate:refresh but be aware that this command will reset all your tables! And then re-run all your migrations.

 

Customise the registration form:

  • Generate the authentication scaffolding which comes bundled with Laravel.
  • Now that we have added the role column to our User model we also need to add the input for the roles in our view so add the select tag input to resources/views/auth/register.blade.php‘s registration form.

    Set-up_role_based_access_control_in_Laravel-registration_form
    The registration form

 

Customise User model and RegisterController:

  • Add the role column to fillable attribute on the User Model so that we can make use of the create() method in Register Controller.
  • Now customize RegisterController.php which is in app/Http/Controllers/Auth directory to include our role input when creating a new user.
    • Add a validation rule for the role field:
    • Add role field to the create() method:

       

Now you should be able to register users with different roles. We’ll create at least one user per each role, and we will move on to implementing the access control logic.

Set-up middlewares:

Middleware provides a convenient mechanism for filtering HTTP requests entering our application. For example, Laravel includes an auth middleware that verifies the user of your application is logged-in.

  • We will create middlewares for each of our roles.
  • Add the following code to respective middlewares which are in app/Http/Middleware folder:
    • Admin.php:
    • Agent.php:
    • Customer.php:
  • Now let’s register our middleware with Laravel. Add the middleware classes to $routeMiddleware property located in app/Http/Kernel.php:

 

Now you can apply these middlewares to routes or to the controller itself:

  • web.php:
  • Or you can specify a middleware in a controller’s constructor, like this:

 

Redirect User After Log-in:

If you use Laravel’s default login setup, you may want to redirect the user to his role specific page after he logs in. and you can do that by overriding the redirectTo() method in your LoginController.php. Make sure you remove the $redirectTo property from your LoginController.php.

Add this to your LoginController.php:

 

That’s it; we have successfully implemented role-based access control in Laravel! And you can adapt this method for as many or as few of the roles you might need.

The example project used in this tutorial is available in my GitHub repository.

If you liked this tutorial, then you might be interested in my other tutorials in the Laravel section and be sure to leave any comments or ask any questions you might have in the comment section below!

P.S:

You can also consider making a small donation to support me. Your donation will directly contribute to the running cost of this website and hopefully my college too 🙂

Paypal: https://www.paypal.me/sapneshnaik | UPI: [email protected]

  • 126
    Shares

65
Leave a Reply

avatar
37 Comment threads
28 Thread replies
36 Followers
 
Most reacted comment
Hottest comment thread
42 Comment authors
Mayavel RRuhithEhsanSapnesh NaikAnirban Deb Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Amratha Tendulkar
Guest
Amratha Tendulkar

?

Harry McKinney
Guest
Harry McKinney

Wow, this is very cool!

Devlim
Guest
Devlim

This work for page level and route level access control. Is there any guide for page element access control? Such as hide delete button for non-admin, disabled edit capability for certain form field access control?

Žymantas
Guest

Nice one 😉

Nikolay Traykov
Guest
Nikolay Traykov

How do you know if the Admin is above the Customer in the hierarchy and that everything that applies to the Customer applies to the Admin as well?

Udaiyar
Guest
Udaiyar

Nice one.

sagagt505
Guest
sagagt505

I have a question? if I want to redirect to different route for different type of user what should i do next? I am newbie for this.

himanshu
Guest
himanshu

this error is irritating me, please help after login —– Trying to get property of non-object D:\xampp\htdocs\authrole\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php protected function addCookieToResponse($request, $response) { $config = config(‘session’); $response->headers->setCookie( new Cookie( ‘XSRF-TOKEN’, $request->session()->token(), $this->availableAt(60 * $config[‘lifetime’]), $config[‘path’], $config[‘domain’], $config[‘secure’], false, false, $config[‘same_site’] ?? null ) ); return $response; }

cristian dumitriu
Guest
cristian dumitriu

I have the same error – did you figure it out?

cristian dumitriu
Guest
cristian dumitriu

I found the problem. Check the handle function in the middleware . I have copied the function wrong. Check them and will be solved.

Kajal
Guest
Kajal

Very nice, thanks for this tutorial 🙂

Cristian
Guest
Cristian

Thank you Naik. I was looking for this.

bila
Guest
bila

Route::get(‘/home’, function(){
echo “Hello Admin”;
})->middleware(‘auth’,’admin’,
‘auth’,’client’
);
how to implement this

mohiminul
Guest
mohiminul

after login—redirect to home in this proces
is it possible to redirect admin panel/agent or/customer panel after login

Eren Christian
Guest
Eren Christian

have a same question

Haidar
Guest
Haidar

in login page if user selected admin how to redirect user to admin page

Eren Christian
Guest
Eren Christian

hi
what to write in protected $redirectTo = ‘/login/checkrole’; in LoginController.php

Anon
Guest
Anon

Thank you so much, very helpful!

Simon
Guest

Really great stuff! work really well

Vincent Libron
Guest
Vincent Libron

say the role field is in another table like
user_type(…){
$table->increment(‘id’);
$table->string(‘type_name’);
}
then the 3 user type is defined in the dbseeder with 1 – admin 2- agent 3-customer
and the user_type table is referenced in the users table.

kiran
Guest
kiran

i have used this when i register it goes directly on auth dashbaord which laravel default and when i used LoginController changed then redirect is not working

pradeep
Guest
pradeep

i got error when i add

protected function redirectTo( ) in my logincontroller, im using auth.
error : Header may not contain more than a single header, new line detected

elodie compain
Guest
elodie compain

me either!

kumar
Guest

protected function redirectTo( ) { if (Auth::check() && Auth::user()->role == ‘customer’) { return ‘/customer’; } elseif (Auth::check() && Auth::user()->role == ‘vendor’) { return ‘/vendor’; } else { return ‘/admin’; } } Mine worked when i removed redirect from return redirect added use Auth; at the top

Dex
Guest
Dex

I have a problem. After registering new account, it redirects me to home which is in HomeController. How can I redirect registered user according to their roles. Thanks

seng ly
Guest
seng ly

After i am login it’s redirect to home page but it is not redirect to Admin, Agent,Customer page. Please help me Thanks!!!

Sagar Basnet
Guest
Sagar Basnet

i am having a error as:ErrorException thrown with message “Header may not contain more than a single header, new line detected” Stacktrace:
#4 ErrorException in E:\xamp\htdocs\TMS\vendor\symfony\http-foundation\Response.php:341
#3 header in E:\xamp\htdocs\TMS\vendor\symfony\http-foundation\Response.php:341
#2 Symfony\Component\HttpFoundation\Response:sendHeaders in E:\xamp\htdocs\TMS\vendor\symfony\http-foundation\Response.php:375
#1 Symfony\Component\HttpFoundation\Response:send in E:\xamp\htdocs\TMS\public\index.php:58
#0 require_once in E:\xamp\htdocs\TMS\server.php:21 help me out from this

Praful Dhabekar
Guest
Praful Dhabekar

I think this is late reply for this question but if someone has similar problem in LoginController they can use
return ‘/customer’;
instead of this return redirect(‘/customer’);

max
Guest
max

this will not work if you want be agent and admin

Samara Ferreira
Guest
Samara Ferreira

thank you very much for this tutorial, all I was needing was him. Congrats

Sugizo
Guest
Sugizo

Thanks bro… Worked in my case clear and clean

Kay
Guest

This tutorial is very straightforward and I must say it has helped me in this school project that I am working on.
I am using the latest Laravel 5.7 so I had to make some few adjustments especially in the LoginController.php. I used protected function authenticated(Request $request, $user) instead of protected function redirectTo( ) .
But it worked perfectly. Thanks very much

Ray Bennett
Guest
Ray Bennett

Sapnesh – this is great – thank you! Hi Kay – Can you elaborate on what you did in 5.7 in the LoginController. After I added everything I continued to get this error: “Method App\Http\Controllers\Auth\LoginController::login does not exist.”

Kay
Guest

In the LoginController i have:

protected function authenticated(Request $request, $user)

instead of:

protected function redirectTo( )

Kay
Guest

Note that i also applied the middlewares to the controller itself. Example in my App\Http\Controllers\AdminController.php
i added:
public function __construct()
{
$this->middleware(‘auth’);
$this->middleware(‘admin’);
}

And in the routes\web.php
i didnt apply the middleware as stated in this tutorial.

FROM:
Route::get(‘/admin’, function(){
echo “Hello Admin”;
})->middleware(‘auth’,’admin’);

TO:
Route::get(‘/admin’, function(){
return view(‘admin’);
});

Ray Bennett
Guest
Ray Bennett

Thank you, Kay. I appreciate the replies!!!

kumar
Guest

You Really saved me. Thanks a lot dear

Jin Min
Guest
Jin Min

Great help. Thank you for your post

John
Guest
John

Thank you very much.

vdem
Guest
vdem

There are built-in features in Laravel for authorization and access control, they are called Gates and Policies, more there: https://laravel.com/docs/5.7/authorization

Dhenn
Guest

Did not work on Laravel 5.7 especially on Login controller and routes, how to fix this?

Class ‘App\Http\Controllers\Auth\Auth’ not found

Praful Dhabekar
Guest
Praful Dhabekar

add this line at the top of your code.
use Auth;

Praful Dhabekar
Guest
Praful Dhabekar

if (Auth::check() && Auth::user()->role == ‘admin’) {
return $next($request);
}
In this code you used User table I presume but already I’ve a table called user_registrations. So my question is how I can use that table in this code.?

Mustafa
Guest
Mustafa

Fatal error: Cannot redeclare App\Http\Kernel::$routeMiddleware in C:\xampp\htdocs\computer\app\Http\Kernel.php on line 80

lee
Guest

ErrorException (E_WARNING)
Header may not contain more than a single header, new line detected

getting this error when logged in

Anirban Deb
Guest
Anirban Deb

but why i can not use this role in blade, like @if(Auth::user()->role == ‘Admin’)
Feature for Admin
@endif
since the role is inside user table i should be able to use it right

Ehsan
Guest
Ehsan

Hy i did everything. But i am getting below error.
“BadMethodCallException
Call to undefined method App\User::roles()”

Ruhith
Guest
Ruhith

wow, that was easy.many thanks bro

Mayavel R
Guest
Mayavel R

thank you so much bro