Laravel — Redirect to different views based on user role

Zeba Rahman
fabcoding
Published in
5 min readAug 5, 2020

Objective

In this tutorial, we shall have a project named ‘mystore’, which can have 2 kinds of users, either ‘admin’ or ‘seller’. They will have separate dashboards with separate features and functionalities. When a user logs in to our website, they will be redirected to a dashboard according to their role. Also, the routes should be protected, meaning, the logged in user should not be able to access the dashboard or any of the inside pages of the other role, even if they type the URL in the browser. So let us begin.

If you are new to Laravel, I recommend going through this article, to learn how to set up Laravel and create and run Laravel projects.

Step 1

Configuring project

After creating the new Laravel project, we will run a couple of quick commands for scaffolding the authentication system.

composer require laravel/ui
php artisan ui vue --auth

and then, run this command to compile it.

npm install && npm run dev

Now run the project in your browser, you should be able to see a working page. You should also be able to click on the LOGIN and REGISTER to go their respective forms and use them to register and login.

Step 2

Set up users, Add role attribute to Users table

We will be using a simple string attribute in the Users table to identify the role of the user. For this example, the user role can either be ‘admin’ or ‘seller’.

Go to the Users table migration. It will be present in a file: mystore/database/migrations/xxx-xxx-xxx_create_users_table.php

Add a string column named ‘role’ which will store the role of the user.

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

Run the command

php artisan migrate

We also need to add this new field to the registration logic.

Open mystore/app/Http/Controllers/Auth/RegisterController.php file. Add a line for the new column in both the validator and the create methods.

protected function validator(array $data) {
return Validator::make($data, [
...
'role' => ['required', 'string', 'max:255'],
]);
}

protected function create(array $data) {
return User::create([
...
'role' => $data['role'],
]);
}

Now let us create 2 users, one for each of our roles: admin and seller. We will do this using seeds. Run the following command to create a seeder

php artisan make:seeder UsersTableSeeder

check mystore/database/seeds for the newly created file UsersTableSeeder.php

Replace the run() method with the following

public function run() {
DB::table('users')->truncate(); //for cleaning earlier data to avoid duplicate entries
DB::table('users')->insert([
'name' => 'the admin user',
'email' => 'iamadmin@gmail.com',
'role' => 'admin',
'password' => Hash::make('password'),
]);
DB::table('users')->insert([
'name' => 'the seller user',
'email' => 'iamaseller@gmail.com',
'role' => 'seller',
'password' => Hash::make('password'),
]);
}

In the same folder, open DatabaseSeeder.php file, and inside the run() method, add the call to our new seeder.

$this->call(UsersTableSeeder::class);

Now run the commands

composer dump-autoload
php artisan db:seed

Now you can test the login using these newly created account credentials

Step 3

Create 2 separate dashboards and routes

Go to mystore/resources/views. Create 2 folders named admin and seller and create a file dashboard.blade.php inside each of these. Let us populate with some basic content for distinction.

admin/dashboard.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Dashboard') }}</div>

<div class="card-body">
@if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif

{{ __('Hello ADMINISTRATOR, You are logged in!') }}
</div>
</div>
</div>
</div>
</div>
@endsection

seller/dashboard.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Dashboard') }}</div>

<div class="card-body">
@if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif

{{ __('Hello SELLER, You are logged in!') }}
</div>
</div>
</div>
</div>
</div>
@endsection

Also, to create controllers, run the following commands

php artisan make:controller Admin/DashboardController
php artisan make:controller Seller/DashboardController

Go to the newly created files under mystore/app/Http/Controllers and modify them to return the views that we created above.

Admin/DashboardController.php

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class DashboardController extends Controller {
public function __construct() {
$this->middleware('auth');
}
public function index() {
return view('admin.dashboard');
}
}

Seller/DashboardController.php

<?php
namespace App\Http\Controllers\Seller;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class DashboardController extends Controller {
public function __construct() {
$this->middleware('auth');
}
public function index() {
return view('seller.dashboard');
}
}

Now create routes for these 2 dashboards.

Go to mystore/routes/web.php file and add the following.

Route::get('/admin_dashboard', 'Admin\DashboardController@index');
Route::get('/seller_dashboard', 'Seller\DashboardController@index');

Now you can open your browser and try the urls with the above routes, and you should see the two distinct skeleton dashboards.

Step 4

Redirect during login

Lets now write the login to check the user role during login and redirect the user to the respective dashbaord.

Go to mystore/app/Http/Controllers/Auth/LoginController.php file.

Find the redirect method

protected $redirectTo = RouteServiceProvider::HOME;

Remove this line and replace it with the below function which checks role and returns route.

public function redirectTo() {
$role = Auth::user()->role;
switch ($role) {
case 'admin':
return '/admin_dashboard';
break;
case 'seller':
return '/seller_dashboard';
break;

default:
return '/home';
break;
}
}

Make sure to include this line at the top, since we are using Auth.

use Illuminate\Support\Facades\Auth;

Also apply the same conditional logic to another file, app/Http/Middleware/RedirectIfAuthenticated.php. Change the handle() method to the following:

public function handle($request, Closure $next, $guard = null) {
if (Auth::guard($guard)->check()) {
$role = Auth::user()->role;

switch ($role) {
case 'admin':
return redirect('/admin_dashboard');
break;
case 'seller':
return redirect('/seller_dashboard');
break;

default:
return redirect('/home');
break;
}
}
return $next($request);
}

And you’re done. You can now go to your browser, and try logging in with the admin and seller accounts, and you will be redirected to the respective dashboards.

Step 5

Protect the routes

For now, if you are logged in as a seller, and you type the admin dashboard route URL in your browser, it works! This is not ideal. We need to protect the routes using a middleware.

In the folder mystore/app/Http/Middleware create a new file Role.php, and add the following code for role check

<?php

namespace App\Http\Middleware;
use Closure;
use Illuminate\Auth\Middleware\Role as Middleware;
use Illuminate\Support\Facades\Auth;

class Role {

public function handle($request, Closure $next, String $role) {
if (!Auth::check()) // This isnt necessary, it should be part of your 'auth' middleware
return redirect('/home');

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

return redirect('/home');
}
}

In case, you want to support multiple roles for a different kind of application, you would pass an array of roles and use foreach to loop through them and check.

Go to app/Http/Kernel.php file and add this middleware to the routeMiddleware array

protected $routeMiddleware = [
...
'role' => \App\Http\Middleware\Role::class,
];

Now let us apply this middleware to our routes. Go back to the mystore/routes/web.php file and modify the route definitions.

Route::get('/admin_dashboard', 'Admin\DashboardController@index')->middleware('role:admin');
Route::get('/seller_dashboard', 'Seller\DashboardController@index')->middleware('role:seller');

That’s it! Now go back to your browser, log in as seller role and try opening the dashboard of the admin role (and vice versa), it should redirect to the given route that is /home.

Originally published at Fabcoding.

--

--