Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Sanctum can be use Multiauth guard

I'm testing with laravel sanctum but here some issues.. I'm creating Admin guard.

enter image description here

When I change the middleware to auth:sanctum_admin.. it should be only can access by admin but here I can access with normal user account with web guard. I don't know why?...I used passport with multiauth package.it's fine. but here in sanctum can't be separate User Table and Admin.

like image 856
Thomas Avatar asked Apr 12 '20 11:04

Thomas


People also ask

Is Laravel sanctum secure?

Laravel Sanctum offers an immaculate, secure, blazingly fast, lightweight authentication system for single-page applications (SPA), mobile applications, and simple, token-based APIs. Sanctum is a profound package that allows every user to generate multiple API tokens for their account independently.

What is Laravel sanctum used for?

Laravel Sanctum provides a featherweight authentication system for SPAs (single page applications), mobile applications, and simple, token based APIs. Sanctum allows each user of your application to generate multiple API tokens for their account.

What is Guard () in Laravel?

Guards define how users are authenticated for each request. For example, Laravel ships with a session guard which maintains state using session storage and cookies. Providers define how users are retrieved from your persistent storage.

Is Laravel sanctum stateless?

HTTP requests are stateless. To authenticate a user, you need to explicitly mention who the user is on every request. This can be done by sending a token that has information about the user, or sending a session ID that the server can use to find the user.


4 Answers

You can, also use multiple guards in sanctum. To achieve this, follow these steps -

  1. Create your own guard as required. (In config/auth.php)
'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
        ],

        'admin' => [
            'driver' => 'session',
            'provider' => 'admins',
        ]
    ],
  1. Set providers. (In config/auth.php)
'providers' => [
       'users' => [
           'driver' => 'eloquent',
           'model' => App\User::class,
       ],

       'admins' => [
           'driver' => 'eloquent',
           'model' => App\Admin::class,
       ],
   ],
  1. Use this guard when you authenticate a user. (In route file)
    if(auth()->guard('admin')->attempt($request->only('email','password')))
    {
        return auth()->guard('admin')->user();
    }
    
like image 68
Abhishek Mitra Avatar answered Oct 20 '22 23:10

Abhishek Mitra


@Abhishek Mitra

and for authorizatioin using Laravel Sanctum in case of Multiple Auth Guard, we can use middleware as such

Route::middleware(['auth:guard_name'])->get('/user', function(){
    return auth()->guard('guard_name')->user();
}
like image 38
Harat Avatar answered Oct 20 '22 22:10

Harat


config/auth.php

driver is sanctum

'guards' => [
    'users' => [
        'driver' => 'sanctum',
        'provider' => 'users',
    ],

    'partners' => [
        'driver' => 'sanctum',
        'provider' => 'partners',
    ],

    'admins' => [
        'driver' => 'sanctum',
        'provider' => 'admins',
    ],

        ],

provider:

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,
    ],
],

model:

must be add Authenticatable

<?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 Admin 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',
    ];
}

Middleware:

Route::middleware(['auth:admin'])->get('/user', function(){
   
}

Guard:

auth()->guard('admin')->user();

Unauthenticated user message:

In app/Exceptions/Handler.php

use Illuminate\Auth\AuthenticationException;

function:

protected function unauthenticated($request, AuthenticationException $exception)
    {
       return response()->json(['message' => 'Unauthenticated.'], 401);

}

or

custom guard and custom redirect

public function render($request, Exception $exception)
{
    $class = get_class($exception);

    switch($class) {
        case 'Illuminate\Auth\AuthenticationException':
            $guard = array_get($exception->guards(), 0);
            switch ($guard) {
                case 'admin':
                    $login = 'admin.login';
                    break;
                default:
                    $login = 'login';
                    break;
            }

            return redirect()->route($login);
    }

    return parent::render($request, $exception);
}
like image 5
ßãlãjî Avatar answered Oct 20 '22 23:10

ßãlãjî


  1. you must add your custom guard in config/auth.php.

'guards' => [

    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'custom-guard' => [
        'driver' => 'session',
        'provider' => 'custom-provider',
    ]
],

be careful, the driver in custom guard must be session. and set provider as:

'providers' => [
   'users' => [
       'driver' => 'eloquent',
       'model' => App\User::class,
   ],

   'custom-provider' => [
       'driver' => 'eloquent',
       'model' => App\CustomProvider::class,
   ],

], the App\CustomProvider::class must be the model. after that can easily use the guard in auth.

auth('custom-guard')->user()
like image 1
Mohammad Bahmanyar Avatar answered Oct 20 '22 21:10

Mohammad Bahmanyar