I'd like to implement authentication in Laravel 11/12. I am using Laravel as an API that is consumed by two Angular SPA's on the same domain (different subdomains): call it the admin frontend and the client frontend.
For the admin frontend, I have an AdminUser
model, with fields email
, password
, role
, foo
, etc., and for the client frontend, a ClientUser
with fields like email
, password
, idNumber
, address
, bar
, etc. I.e., the different user types require different fields.
Both frontends are protected by login pages. Since both SPAs are on the same domain as the API, I will be using sanctum's SPA auth
for both, which is just cookie-based session authentication. The Laravel documentation uses the default web
guard in all auth examples, which uses the default User
model that comes with Laravel.
So I have (to my knowledge) 2 options:
User
model for all SPA auth.
To do this, I would add a type
field to User
(where the type can be 'admin' or 'client') and then check the type
upon authentication. I.e., check that the user type is 'admin' before giving access to an admin endpoint and check that the user type is 'client' before giving access to a client endpoint. For the extra type-specific user fields, just add a foreign key to the User.id
field in both AdminUser
and ClientUser
models.config/auth.php
for all the different user types. So add 'client' and 'admin' guards.Option 1 seems easier in the sense that it is "well documented". Option 2 seems "cleaner" but has very little documentation (that I can find at least) - the docs only sort of mention that it is possible. There are forum examples out there for option 2, but all of them differ... I can't find a consistent answer.
I would greatly appreciate the advice of someone who has come across the same issue.
I have the same setup where there's an admin login screen (admin.test.com) and end user login screen (mypage.test.com) using Laravel sanctum and Nuxt frontend.
I went with option 2, where I've configured multiple guards.
auth.php
'guards' => [
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
'providers' => [
'admins' => [
'driver' => 'eloquent',
'model' => \App\Models\Admin::class,
],
'users' => [
'driver' => 'eloquent',
'model' => env('AUTH_MODEL', \App\Models\User::class),
],
],
In your routing, you'll simply have to use the auth
middleware with the guard option.
Route::group(['prefix' => 'admin', 'as' => 'admin.'], function () {
Route::group(['middleware' => 'auth:admin'], function () {
// Admin api endpoints
});
});
Route::group(['prefix' => 'customer', 'as' => 'customer.'], function () {
Route::group(['middleware' => 'auth:web'], function () {
// User api endpoints
});
});