larsb-dev's avatar

Series that covers multi role authentication?

A user should see a different dashboard from an admin, but both use the same /login route to log in.

Is there a series on Laracasts where I can learn this?

1 like
9 replies
LaryAI's avatar
Level 58

Certainly! To implement multi-role authentication where both admins and regular users share the same /login route but see different dashboards, you can use Laravel’s built-in authentication with some customization.

1. Database Design

Make sure your users table has a role column (e.g., admin, user).

php artisan make:migration add_role_to_users_table --table=users

In the migration:

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->string('role')->default('user');
    });
}

2. Authentication Logic

After login, redirect users based on their role. In app/Http/Controllers/Auth/LoginController.php, override the authenticated method:

protected function authenticated(Request $request, $user)
{
    if ($user->role === 'admin') {
        return redirect('/admin/dashboard');
    }
    return redirect('/user/dashboard');
}

3. Route Protection

In your routes/web.php:

Route::middleware(['auth', 'role:admin'])->group(function () {
    Route::get('/admin/dashboard', [AdminController::class, 'dashboard']);
});

Route::middleware(['auth', 'role:user'])->group(function () {
    Route::get('/user/dashboard', [UserController::class, 'dashboard']);
});

You’ll need a role middleware. Create it with:

php artisan make:middleware RoleMiddleware

In app/Http/Middleware/RoleMiddleware.php:

public function handle($request, Closure $next, $role)
{
    if (auth()->check() && auth()->user()->role == $role) {
        return $next($request);
    }
    abort(403, 'Unauthorized');
}

Register it in app/Http/Kernel.php:

'role' => \App\Http\Middleware\RoleMiddleware::class,

4. Login Route

Both admins and users log in from /login as usual.

Summary

  • Add a role to users.
  • Redirect after login based on role.
  • Protect dashboards with role-based middleware.

Recommended Series on Laracasts:
Check out "Multi-Authentication in Laravel" for an in-depth walkthrough.

Let me know if you need code for a specific part!

larsb-dev's avatar

I don't think that's the latest Laravel way of doing it. I read somewhere the Kernel approach is no longer the one.

1 like
jlrdw's avatar

You use authentication for login, you need authorization to determine who can do what.

One of my apps goes like this:

  • Bob is an admin

  • Suzy is admin and does bookkeeping

  • Mary is a bookkeeper only

  • If Bob is logged in, Bob can only do admin stuff and all access to user stuff. But Bob cannot mess with bookkeeping.

  • If Suzy is logged in she can access admin stuff and bookkeeping and accounting stuff.

  • If Mary is logged in she cannot mess with admin stuff, but has access to bookkeeping and accounting stuff.

So I just check at method or route as needed level if the logged in users role can or cannot access that method / function.

And use query scopes to let a user edit / view their own data or an admin can access all users data. Depending on your app and use case.

Bottom line: A logged in user with their role /s either can or cannot do something.

1 like
vincent15000's avatar

I have developed an application where the dashboard isn't the same for each role.

An authenticated user who loads the dashboard page is automatically redirect to his/her own dashboard according to his/her role via the DashboardController.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DashboardController extends Controller
{
    public function __invoke()
    {
        $role = auth()->user()->role->value;

        return $this->$role();
    }

    public function __call($name, $arguments)
    {
        return view("dashboards.$name");
    }
}

The _invoke() function identifies the authenticated user and executes for example the admin() or manager() function via the __call function.

The call() function identifies the name of the function and displays the right view according to the role, for example dashboards.admin or dashboards.manager.

1 like
vincent15000's avatar

And now when I write my previous answer, I see that the __call() function isn't necessary.

public function __invoke()
{
    $role = auth()->user()->role->value;
	
	return view("dashboards.$role");
}
1 like
larsb-dev's avatar

Nice, thanks. So by calling user()->role->value we get the role associated with that user via the foreign key of the roles table?

If I use this approach I won't need to use any guards or middleware?

Snapey's avatar

be careful about your terminology. Authentication controls if a user can login, Authorization relates to what they can do.

Find out who they are first. Don't be tempted by the fact that it is possible to use multiple guards. Multiple guards never produce a better solution IMO.

Please or to participate in this conversation.