In this blog, we will go over the steps to create Multiple Role Based Authentication and Access Control in Laravel Application with a detailed explanation of the code.
Getting Started
We will start by installing a fresh new Laravel project to demonstrate
Step 1:
The following command can be used to install a fresh Laravel project, or you can check the documentation here.
1 |
composer create-project --prefer-dist laravel/laravel MultiAuth |
Step 2:
Setting Databases
Next, let’s set up our database and configure our .env
file to connect to our database properly
1 2 3 4 5 6 |
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=DB NAME HERE DB_USERNAME=DB USERNAME HERE DB_PASSWORD=DB PASSWORD HERE |
Step 3:
Now we need to customize the users_table under migration as per our requirement.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateUserTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create("users", function (Blueprint $table) { $table->increments("id"); $table->bigInteger("role_id"); $table->string("name"); $table->string("email")->unique(); $table->timestamp("email_verified_at")->nullable(); $table->string("password"); $table->rememberToken(); $table->timestamps(); }); } /** * Run the migrations. * * @return void */ public function down() { Schema::dropIfExists("User"); } } ?> |
Now we have to create a model and migration for the role table where we can see the different roles that can login like ‘admin’, ‘user’ etc.
1 |
php artisan make:model Role -m |
In the roles table, we will customize the Schemas as per the requirement.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateRoleTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create("roles", function (Blueprint $table) { $table->bigIncrements("role_id"); $table->string("role_name"); $table->string("role_slug"); $table->timestamps(); }); } /** * Run the migrations. * * @return void */ public function down() { Schema::dropIfExists("Role"); } } ?> |
Step 4:
So now we have two models named Users and Roles and both are dependent on each other hence we need to make a relationship between them.
To create a relationship we will create functions in both the model for the other one by giving the command given below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class role extends Model { use HasFactory; /** * User's relation with Roles. * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function users() { return $this->hasMany("App\User"); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; /** * The attributes that are mass assignable. * * @var array<int, string> */ protected $fillable = ["name", "email", "password"]; /** * The attributes that should be hidden for serialization. * * @var array<int, string> */ protected $hidden = ["password", "remember_token"]; /** * The attributes that should be cast. * * @var array<string, string> */ protected $casts = [ "email_verified_at" => "datetime", ]; /** * Get the roles of user * *@return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function roles() { return $this->belongsTo("App\Role"); } } |
Step 5:
In the next step, we need to create seeders for each of the models (User, Role). To create the UsersTableseeder and RolesTableSeeder
1 2 |
php artisan make:seed UsersTableSeeder php artisan make:seed RolesTableSeeder |
After the following step, we need to add insert function in the UsersTableseeder and RolesTableSeeder and also declare the use Illuminate\Support\Facades\DB; in both the seeders in the beginning since we will be using the DB class in the seeders.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?php namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; class RoleTableSeeder extends Seeder { /** * Run the database seeds. */ public function run(): void { DB::table("roles")->insert([ "role_name" => "Admin", "role_slug" => "admin", ]); DB::table("roles")->insert([ "role_name" => "User", "role_slug" => "user", ]); DB::table("roles")->insert([ "role_name" => "Manager", "role_slug" => "manager", ]); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<?php namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; class UsersTableSeeder extends Seeder { /** * Run the database seeds. */ public function run(): void { DB::table("users")->insert([ "role_id" => "1", "name" => "Admin", "email" => "admin@gmail.com", "password" => bcrypt("pass@admin"), ]); DB::table("users")->insert([ "role_id" => "2", "name" => "User", "email" => "user@gmail.com", "password" => bcrypt("pass@user"), ]); DB::table("users")->insert([ "role_id" => "3", "name" => "Manager", "email" => "manager@gmail.com", "password" => bcrypt("pass@manager"), ]); } } |
Once done with the database creation we will migrate our tables into the database with the command given below.
1 |
php artisan migrate |
In the next step we need to define two created seeders files (UsersTableSeeder and RolesTableSeeder) into the DatabaseSeeder.php as shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php namespace Database\Seeders; // use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. */ public function run(): void { $this->call(UsersTableSeeder::class); $this->call(RolesTableSeeder::class); } } |
Now we need to import our data stored in the Seeder files into the database which we created using the command:
1 |
php artisan db:seed |
Step 6:
Until here we have set up the database for storing the details which will be provided by the user and now we need to create the controllers and the middleware to authenticate and redirect the users to there respective pages.
First of all, we need to create a controller for the User and the Admin.
To create the controller we need to follow the command given below:
1 2 |
php artisan make:controller Admin/AdminController php artisan make:controller User/UserController |
Now we will be creating middleware for the authentication of the Admin and the User.
1 2 |
php artisan make:middleware AdminMiddleware php artisan make:middleware UserMiddleware |
Now we will add Auth trait in the AdminMiddleware and UserMiddleware for authentication of the User and the Admin by writing use Auth;
In the next step we will add handle() function in the AdminMiddleware and UserMiddleware.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; class AdminMiddleware { /** * Handle an incoming request. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next): Response { if (auth::check() && Auth::user()->role_id == 1) { return $next($request); } else { return redirect()->route("login"); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; class UserMiddleware { /** * Handle an incoming request. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next): Response { if (auth::check() && Auth::user()->role_id == 2) { return $next($request); } else { return redirect()->route("login"); } } } |
We will also implement a Condition for Admin and User Login in RedirectIfAuthenticated which is in app/Http/Middleware/RedirectIfAuthenticated.php.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<?php namespace App\Http\Middleware; use App\Providers\RouteServiceProvider; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Symfony\Component\HttpFoundation\Response; use Auth; class RedirectIfAuthenticated { /** * Handle an incoming request. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next, string ...$guards): Response { if (Auth::guard($guard)->check() && Auth::user()->role_id == 1) { return redirect()->route("admin.dashboard"); } elseif (Auth::guard($guard)->check() && Auth::user()->role_id == 2) { return redirect()->route("user.dashboard"); } else { return $next($request); } } } |
Step 7:
Now we need the default auth system to login and register users. Here, we will use laravel ui
package and create auth scaffold with the Bootstrap framework. let’s follow bellow command:
1 |
composer require laravel/ui |
Now create a simple bootstrap auth system:
Now we will be implementing a condition in the login controller before that we will remove ‘/home’ from protected $redirectTo = ‘/home’; since we don’t want to redirect the page to Home after logging in.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; use Illuminate\Foundation\Auth\AuthenticatesUsers; class LoginController extends Controller { /* |-------------------------------------------------------------------------- | Login Controller |-------------------------------------------------------------------------- | | This controller handles authenticating users for the application and | redirecting them to your home screen. The controller uses a trait | to conveniently provide its functionality to your applications. | */ use AuthenticatesUsers; /** * Where to redirect users after login. * * @var string */ protected $redirectTo = RouteServiceProvider::HOME; /** * Create a new controller instance. * * @return void */ public function __construct() { if (Auth::check() && Auth::user()->role_id == 1) { $this->redirectTo = route("admin.dashboard"); } elseif (Auth::check() && Auth::user()->role_id == 2) { $this->redirectTo = route("user.dashboard"); } $this->middleware("guest")->except("logout"); } } |
Likewise, we will implement the condition in the ResetPasswordController and remove ‘/home’ from protected $redirectTo = ‘/home’;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; use Illuminate\Foundation\Auth\ResetsPasswords; class ResetPasswordController extends Controller { /* |-------------------------------------------------------------------------- | Password Reset Controller |-------------------------------------------------------------------------- | | This controller is responsible for handling password reset requests | and uses a simple trait to include this behavior. You're free to | explore this trait and override any methods you wish to tweak. | */ use ResetsPasswords; /** * Where to redirect users after resetting their password. * * @var string */ protected $redirectTo; /** * Create a new controller instance. * * @return void */ public function __construct() { if (Auth::check() && Auth::user()->role_id == 1) { $this->redirectTo = route("admin.dashboard"); } elseif (Auth::check() && Auth::user()->role_id == 2) { $this->redirectTo = route("user.dashboard"); } $this->middleware("guest")->except("logout"); } } |
Step 8:
Once we are done with the above steps we will use AdminMiddleware and UserMiddleware in Kernal.php which is in app/Http/Kernel.php.
1 2 |
use App\Http\Middleware\AdminMiddleware; use App\Http\Middleware\UserMiddleware; |
After that, we need to define and for defining we will add the command given below in routeMiddleware.
1 2 |
'admin' => AdminMiddleware::class, 'user' => UserMiddleware::class, |
Now we are almost done with it and need to write the routes for the Admin and the User.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?php use App\Http\Controllers\AdminController; use App\Http\Controllers\UserController; /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return redirect('login'); }); Auth::routes(); Route::get('/home', 'HomeController@index')->name('home'); Route::group(['as'=>'admin.','prefix' => 'admin','namespace'=>'Admin','middleware'=>['auth','admin']], function () { Route::get('dashboard', [AdminController::class, 'index'])->name('dashboard'); }); Route::group(['as'=>'user.','prefix' => 'user','namespace'=>'User','middleware'=>['auth','user']], function () { Route::get('dashboard', [UserController::class, 'index'])->name('dashboard'); }); |
Almost done but we need to make the views as well where we can redirect the admin or user once they login.
-Create a blade file for the Admin dashboard under resource/views/admin/dashboard.blade.php.
-Create a blade file for the User dashboard under resource/views/user/dashboard.blade.php.
Under the dashboard blades of User and Admin, we can write the basic HTML to check whether it is showing it when redirected.
1 2 3 4 5 6 7 8 9 10 11 12 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Admin Dashboard</title> </head> <body> <h1>Welcome to Admin Dashboard</h1> </body> </html> |
1 2 3 4 5 6 7 8 9 10 |
<head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>User Dashboard</title> </head> <body> <h1>Welcome to User Dashboard</h1> </body> </html> |
Thank you for reading my blog. If you have any queries you can free to contact me in the comment section.
Additionally, if you’re looking for custom solutions, you can hire Laravel developers, for your customised solutions. For exploring the available extensions for Bagisto, you can check out our extensions.