Kritim Yantra
Mar 21, 2025
In modern web applications, it's common to have multiple types of users, each with different roles and permissions. For example, an e-commerce platform might have administrators, sellers, and customers—each requiring different levels of access. Laravel 12 makes it easy to implement such a multi-authentication system. In this blog, we'll explore how to set up a Laravel 12 Multi Auth System using the Spatie Laravel Permissions package.
Spatie Laravel Permissions is a powerful package that allows you to manage user roles and permissions in a Laravel application. It provides a simple and flexible way to assign roles to users and permissions to roles, making it easier to control access to different parts of your application.
composer create-project --prefer-dist laravel/laravel multi-auth
composer require spatie/laravel-permission
.env
file is correctly configured with your database credentials.
First, let's create the necessary tables for our multi-auth system. We'll need tables for users, roles, and permissions.
Run the following command to publish the Spatie package's migration files:
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
Then run the migrations:
php artisan migrate
Next, configure the User
model to use the Spatie package.
Open app/Models/User.php
and add the HasRoles
trait:
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
// Other model properties and methods
}
In a multi-auth system, you might have different types of users such as admin
, seller
, and customer
.
Open config/auth.php
and define multiple guards:
<?php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'seller' => [
'driver' => 'session',
'provider' => 'sellers',
],
'customer' => [
'driver' => 'session',
'provider' => 'customers',
],
],
Next, define the providers for each guard:
<?php
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
'sellers' => [
'driver' => 'eloquent',
'model' => App\Models\Seller::class,
],
'customers' => [
'driver' => 'eloquent',
'model' => App\Models\Customer::class,
],
],
Now, let's create models for each user type. Run the following commands:
php artisan make:model Admin -m
php artisan make:model Seller -m
php artisan make:model Customer -m
Open each migration file and define the necessary columns. For example, the admins
table migration might look like:
<?php
public function up()
{
Schema::create('admins', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
Repeat similar steps for the sellers
and customers
tables, then run:
php artisan migrate
Configure each model to use the HasRoles
trait and set the appropriate guard.
For example, in app/Models/Admin.php
:
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
class Admin extends Authenticatable
{
use HasRoles;
protected $guard = 'admin';
// Other properties and methods
}
Repeat this configuration for the Seller
and Customer
models with their respective guards.
Create a seeder to set up initial roles and permissions:
php artisan make:seeder RolesAndPermissionsSeeder
In database/seeders/RolesAndPermissionsSeeder.php
, add:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
class RolesAndPermissionsSeeder extends Seeder
{
public function run()
{
// Reset cached roles and permissions
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
// Create permissions
Permission::create(['name' => 'edit articles']);
Permission::create(['name' => 'delete articles']);
Permission::create(['name' => 'publish articles']);
Permission::create(['name' => 'unpublish articles']);
// Create roles and assign permissions
$role = Role::create(['name' => 'admin']);
$role->givePermissionTo(['edit articles', 'delete articles', 'publish articles', 'unpublish articles']);
$role = Role::create(['name' => 'seller']);
$role->givePermissionTo(['edit articles', 'publish articles']);
$role = Role::create(['name' => 'customer']);
$role->givePermissionTo(['edit articles']);
}
}
Run the seeder:
php artisan db:seed --class=RolesAndPermissionsSeeder
When creating users, assign them roles using the assignRole
method. For example:
<?php
$admin = Admin::create([
'name' => 'Admin User',
'email' => 'admin@example.com',
'password' => bcrypt('password'),
]);
$admin->assignRole('admin');
$seller = Seller::create([
'name' => 'Seller User',
'email' => 'seller@example.com',
'password' => bcrypt('password'),
]);
$seller->assignRole('seller');
$customer = Customer::create([
'name' => 'Customer User',
'email' => 'customer@example.com',
'password' => bcrypt('password'),
]);
$customer->assignRole('customer');
Use middleware to restrict access based on roles. For example, to restrict the admin dashboard:
<?php
Route::middleware(['auth:admin', 'role:admin'])->group(function () {
Route::get('/admin/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard');
});
Route::middleware(['auth:seller', 'role:seller'])->group(function () {
Route::get('/seller/dashboard', [SellerController::class, 'dashboard'])->name('seller.dashboard');
});
Route::middleware(['auth:customer', 'role:customer'])->group(function () {
Route::get('/customer/dashboard', [CustomerController::class, 'dashboard'])->name('customer.dashboard');
});
In your controllers, you can check for permissions using the can
method:
<?php
public function editArticle(Article $article)
{
if (auth()->user()->can('edit articles')) {
// The user can edit articles
} else {
// The user does not have permission
}
}
Create login and registration controllers for each user type (admin, seller, customer) and set up corresponding views. For example, to create a login controller for admins:
php artisan make:controller Auth/AdminLoginController
In AdminLoginController
, handle the login logic:
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminLoginController extends Controller
{
public function showLoginForm()
{
return view('auth.admin.login');
}
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::guard('admin')->attempt($credentials)) {
return redirect()->intended('/admin/dashboard');
}
return back()->withErrors([
'email' => 'The provided credentials do not match our records.',
]);
}
public function logout()
{
Auth::guard('admin')->logout();
return redirect('/');
}
}
Repeat this process for sellers and customers.
In this blog, we've walked through the process of setting up a Laravel 12 Multi Auth System using the Spatie Laravel Permissions package. We covered how to configure multiple authentication guards, create models for different user types, seed roles and permissions, protect routes with middleware, and check permissions in controllers.
With this setup, you can easily manage multiple user types with different roles and permissions in your Laravel 12 application. This approach is flexible and can be extended to fit the needs of your specific application.
Happy coding! 🚀
No comments yet. Be the first to comment!
Please log in to post a comment:
Continue with Google