You can have multiple guards using sanctum as a driver, with multiple providers each using a different Eloquent Model.
In you ./config/auth.php file, add these guards:
'guards' => [
'users' => [
'driver' => 'sanctum',
'provider' => 'users',
],
'partners' => [
'driver' => 'sanctum',
'provider' => 'partners',
],
'admins' => [
'driver' => 'sanctum',
'provider' => 'admins',
],
// ...
],
And in the same file add these providers:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'partners' => [
'driver' => 'eloquent',
'model' => App\Models\Partner::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
Models App\Models\User, App\Models\Partner, and App\Models\Admin will need to implement the Authenticatable interface.
So you could just copy the User model as a base to the Partner and Admin ones, for example:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class Partner extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Then in your controllers, and/or route definitions you would use: auth:users for routes that should be for users only, auth:partners for routes that should be for partners only, and auth:admins for routes that should be for admins only.
===
Some thoughts on multiple models authentication
Although I think having multiple guards and providers have valid use cases, (I even use this approach in some apps), by your description I think you would be better using a single User model with a belongsToMany relation to a roles table. You can even use Spatie's package for roles and permissions management.
The additional fields needed for regular users, partners and admins can be added to tables with a belongsTo/hasOne relation. I also use this other approach, in this particular project the additional table for regular users is called members.
The decision point on using one user model or multiple user models is if a screen/route/resource can be accessed by different roles.
The app where I use multiple tables for different roles is a custom e-commerce platform. So a member never sees the admin screens, and while an admin can have a member account (using the same e-mail), if we consider only the data aspect of it, they have access to completely different screens than a member. Essentially it is like two separate apps that share the same DB, but I keep them in the same codebase as they share some business logic related code.
Phrasing it differently, I would go with multiple tables for different roles if each access level access looks like they are accessing a completely different app that shares the same DB.
If different roles have just different permissions on the same set of screens/resources, them I would go with a single users table and model for authentication, use a role management package, and store different fields needed in a related table using a one-to-one relation.
But these are just my two cents, in the end of day use what fits better to your app's requirements and team's preferences.
Hope it helps somehow.