DEV Community

Multiple role-based authentication in Laravel

Solomon Eseme on January 26, 2019

Hey guys, in this article, am going to show you how toimplement multiple role-based authentication in Laravel even if you have many different users...
Collapse
 
martin_betz profile image
Martin Betz • Edited

And here's another refactor to make it even conciser and easier to read and change. It is using a lookup array to isolate changes (just add a new item to the array for a new role) and have one execution path (one redirect line instead of 5).

public function handle($request, Closure $next)
    {
        if (!Auth::check()) {
            return redirect()->route('login');
        }

        if (Auth::user()->role == 3) {
            return $next($request);
        }

        $destinations = [
            1 => 'superadmin',
            2 => 'admin',
            4 => 'team',
            5 => 'academy',
            6 => 'scout',
        ];

        return redirect(route($destinations[Auth()::user()->role]));
    }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
kaperskyguru profile image
Solomon Eseme

I'm Having errors after implementing this.
I logged in as academy then try to visit the admin dashboard by typing the route to it in the browser and i got this -> "Call to undefined method Illuminate\Auth\AuthManager::user()"

Collapse
 
computermaverick profile image
⚓Timmy Iwoni ⚓

In Martin's implementation there's a typo of the parenthesis when calling the Auth facade... So instead of Auth()::user()->role, it should be Auth::user()->role

Thread Thread
 
kaperskyguru profile image
Solomon Eseme

Oh that's true.. I will fix that..

Collapse
 
martin_betz profile image
Martin Betz

I'll replicate it soon, probably I just have a typo somewhere.

Thread Thread
 
kaperskyguru profile image
Solomon Eseme

Sure. I will be expecting.

Collapse
 
baronsindo profile image
𝙹𝚒𝚋𝚛āʾī𝚕 ⚡

a comment that make me awkwardly happy

Collapse
 
kaperskyguru profile image
Solomon Eseme

Wow.. it's getting more clean and clear.. Thanks for the update.

Collapse
 
martin_betz profile image
Martin Betz • Edited

May I propose a refactor for the handle method? You could save some duplications by flipping the logic. If you first ask for if the user is not logged in, redirect to login you catch this case once and can skip it for everything that follows. Also, instead of elseelse, you can simply use ifif. If a case proves true, you return something and the function stops, so you do not need an else. This reduces cognitive load.

public function handle($request, Closure $next)
{
    if (! Auth::check()) {
        return redirect()->route('login');
    }

    if (Auth::user()->role == 1) {
        return redirect()->route('superadmin');
    }

    if (Auth::user()->role == 5) {
        return redirect()->route('academy');
    }

    if (Auth::user()->role == 6) {
        return redirect()->route('scout');
    }

    if (Auth::user()->role == 4) {
        return redirect()->route('team');
    }

    if (Auth::user()->role == 3) {
        return $next($request); 
    }

    if (Auth::user()->role == 2) {
        return redirect()->route('admin');
    }
}
Collapse
 
picwellwisher12pk profile image
Amir Hameed

What about switch statement?

Collapse
 
martin_betz profile image
Martin Betz

Yes, switch would cut some duplicate lines. I would still propose the lookup array pattern as recommended in this extra comment as it is a lot easier to add and cut arguments and is super easy to read.

Thread Thread
 
picwellwisher12pk profile image
Amir Hameed

These if statements could also be one-liners to save some more characters and space.

Thread Thread
 
martin_betz profile image
Martin Betz

Yes, but there still would be lots of repetitions even in short-form. Maybe I can write an own article soon about possible refactorings so that people can learn and compare. The original poster went with the simple if solution but there are multiple ways to make it shorter and easier to maintain.

Thread Thread
 
picwellwisher12pk profile image
Amir Hameed

Indeed.
Tell me where can I start a new discussion?

Thread Thread
 
martin_betz profile image
Martin Betz

Just put a comment on the root of this article: dev.to/kaperskyguru/multiple-role-...

Collapse
 
kaperskyguru profile image
Solomon Eseme

This is great, thanks for your contribution, I will refactor immediately.

Collapse
 
kaperskyguru profile image
Solomon Eseme

Updated now..

Collapse
 
omaresmael profile image
omaresmael • Edited

It was a beautiful tutorial, there is a routing refactor must be done tho, in order to function properly in laravel 8

Route::get('/player', [PlayerController::class,'index'])->name('player')->middleware('player');

instead of

Route::get('/player', 'PlayerController@index')->name('player')->middleware('player');

there are other ways to solve this problem but that just my favorite one

Collapse
 
vncdigitalservices profile image
VNC Digital Services Pvt Ltd

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?

Collapse
 
kaperskyguru profile image
Solomon Eseme • Edited

You can use action based control, like Spartia library for such.
github.com/spatie/laravel-permission

Collapse
 
raviameriya profile image
Ravi K. Ameriya • Edited

created role middleware but getting an error

error: Attempt to read property "role" on null

middleware function below as :
public function handle(Request $request, Closure $next)
{
if (!Auth::check()) {

        return redirect()->route('login');
    }

    if (Auth::check() && Auth::user()->role == 1) {

        return $next($request);
        //return redirect()->route('dashboardShow');
    }

    if (Auth::check() && Auth::user()->role == 2) {


        return $next($request);
        //dd('user');
    }

    abort(404);  // for other user throw 404 error

}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
rvp04 profile image
VP • Edited

i used your code and i am getting this error

127.0.0.1 redirected you too many times.

Collapse
 
boypanjaitan16 profile image
Boy Panjaitan

How if the user have multiple account with different roles,but with the same credentials ? I assumed this nice guide not covered it yet :)

Collapse
 
mrdionjr profile image
Salomon Dion • Edited

In that case, create a separate table for roles and permissions (spatie/laravel-permission can help). Then, create the permissions and roles and assign permissions to roles. I would recommend as best practice to rely mainly on permissions in your applications as differents roles may have common permissions. Now, when a user is created assign him a role, and rely on this first role for redirect ($user->roles()->id). You can have a menu where he can switch to another dashboard based on his roles. Hope it helps.

Collapse
 
kaperskyguru profile image
Solomon Eseme

Yes the article didn't cover that. But I will suggest you use OTP to implement such scenerios.

Collapse
 
estern_winluck profile image
Estern Winluck

Great!
I wish to know how to handle when a user has multiple roles ie. superadmin and admin

Collapse
 
ryan1 profile image
ryan

Nice, this was a great tutorial!