Spatie role and permission error when using middleware('auth:sanctum') - laravel

When I'm creating new users and assign them roles and permissions it works fine,
but when I assign role using protected route
Route::post('/excel/upload', [ExcelController::class,'upload'])->name('uploadExcel')->middleware('auth:sanctum');
i get and error:
Spatie\Permission\Exceptions\GuardDoesNotMatch
The given role or permission should use guard web instead of sanctum.
auth.php
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
the guard_name in the Spatie role and permissions tables set to web.
I understand that there's a problem with the guard_name configuration, I just can't
figure out how to solve it.
Any help would be appreciated

Insert the below code to auth/config.php file
'guards' => [
...
'sanctum' => [
'driver' => 'sanctum',
'provider' => 'users'
]
],

Related

Laravel Passport: how to customize the authentication guard for the user provider in your application

Laravel by default creates the model and the User table. The problem is that I create and use the table in the database, a model and a controller called Citizen.
And here comes my doubt, when we configure laravel-passport we must specify the guard, this is the Laravel example:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
What is the provider? Taking into account this line:
'provider' => 'users',
Should I use 'provider' => 'citizen', instead of 'provider' => 'users'?
You can create custom provider. This has to be done in config/auth.php
There is one provider named users by default. You can create your own guard and providers as follows:
guards:
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
'citizens' => [
'driver' => 'passport',
'provider' => 'citizens',
],
],
In the providers section:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'citizens' => [
'driver' => 'eloquent',
'model' => App\Models\Citizen::class, //path to your model
],
],
Now you can use the middleware with custom guard by using auth:citizens as middleware.
For example, in route file,
Route::middleware('auth:citizens')->group(function(){
});

Does Laraven's sanctum replace the default authentication?

I've been browsing many questions related to using multi-auth, sanctum and SPA. I've also read the documentation multiple times. I'm confused about how this works.
Currently I have 2 route groups: web and api. Web group outputs different HTML templates and front-end content and so, and the API route generates content that is used to fill those templates.
I also have 2 different types of users, admins and clients. Each have access to certain routes of web and api.
I'm using 2 guards to protect the web routes, which works just fine:
'guards' => [
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'client' => [
'driver' => 'session',
'provider' => 'clients',
],
],
And the providers:
'providers' => [
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
'clients' => [
'driver' => 'eloquent',
'model' => App\Models\Client::class,
],
],
Now I have trouble protecting the API routes. I've followed the instructions, set X-XSRF-TOKEN header, added sanctum to middlewares but I always get a 401 response. I'm not sure how to setup my guards. Should I add 2 more guards to the array? Such as:
'guards' => [
// Web
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'client' => [
'driver' => 'session',
'provider' => 'clients',
],
// API
'sanctum_admin' => [
'driver' => 'sanctum',
'provider' => 'admins',
],
'sanctum_client' => [
'driver' => 'sanctum',
'provider' => 'clients',
],
],
And then use add the auth:sanctum_admin middleware to my API routes? Because this doesn't work either. Should I remove the original guards and only use sanctum? Is this even possible to have multiple guards for both web and API? Really confused about how this works. Any help is appreciated.

What happens to the access token in the multiple auth of Laravel passport

Configure the auth.php config file as below:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
'admin-api' => [
'driver' => 'passport',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
I successfully generate access_token for both user and admin.
However, if I get the user's access_token to access the api admin route ('middleware' => 'auth:admin-api'), it succeeds.
The information received by request()->user() is the admin account with the same id as the user.
Same thing happens when I use admin token for user access and api.
Note:
This scenario only happens when admin and user have the same ID value.
What is going on, or did I do something wrong?
I guess the scenario that happened was as follows:
Step 1: user's access_token passes 'middleware' => 'auth:admin-api'.
Step 2: The oauth_access_tokens.user_id value is returned
Step 3: From user_id will return the corresponding admin.
So it happens only when user.id and admin.id are same.
Help me clarify this issue. Thanks
If i want to prevent this, what should I do?
Obviously users shouldn't access the admin account-only api

How can I use web's guard and api's guard both in laravel project?

I have a problem with authentication in laravel.
I added jwt auth in my project, because i need an authentication with token, but to use it I have to change default's guard in file "auth.php"
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
And here there is a problem, because if I change default's guard from 'web' to 'api' login route doesn't work anymore.
How can I solve this problem?
Thank you all.
To use both, change the api driver from 'token' to 'jwt' in auth guards. Leave defaults to as it is.
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],

Laravel Multiple Auth::attempt

I have two models in my laravel v5.4 project, user and admin.
In config/auth.php i added admin to guards and providers as below :
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
Now in AdminController class i want to use Auth::attempt function but by default it uses the users table. I can change defaults in config/auth.php as below and it works but in this case i can not use Auth::attempt for users.
'defaults' => [
'guard' => 'admin',
'passwords' => 'users',
],
I want to set user as default but use Auth::attempt function for admin with a method like Auth::attempt('admin',[credentials]). How can i use Auth::attempt for Admin model?
You call the guard directly, like this:
Auth::guard('admin')->attempt($credentials);
Or with the helper:
auth()->guard('admin')->attempt($credentials);
Or, even shorter with the helper:
auth('admin')->attempt($credentials);

Resources