12

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.

Tom
  • 4,070
  • 4
  • 22
  • 50
Thomas
  • 121
  • 1
  • 1
  • 3

8 Answers8

12

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();
    }
    
Stanley
  • 499
  • 1
  • 7
  • 15
  • 1
    Welcome! Thanks for the contribution. Can I ask that you copy the code from the images and place them into the markdown? We try to avoid screenshots of code on Stack Overflow because they're hard for other users to copy and paste from and they don't show up in search results (e.g., if someone is searching by keywords in them). – Jeremy Caney May 10 '20 at 02:36
  • Driver should be 'sanctum' in auth config. – Raush Jun 25 '22 at 13:45
8

@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();
}
Harat
  • 1,340
  • 1
  • 17
  • 20
5

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);
}
Balaji
  • 9,657
  • 5
  • 47
  • 47
0
  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()
0

In config/auth.php:

'guards' => [
    ...

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

(Tested in Laravel 9.x)

edu.dev.ar
  • 31
  • 3
0

I also face the same issue and solved it by following -

  1. In auth.php add an extra Guard - front
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'front' => [
            'driver' => 'session',
            'provider' => 'members',
        ],
    ],
    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => Vanguard\User::class,
        ],

        'members' => [
             'driver' => 'eloquent',
             'model' => Vanguard\Member::class,
        ],
    ],
  1. Log in as a Default User or Member
/** Default Guard**/
if (Auth::attempt(['username' => $credentials['username'], 'password' => $credentials['password']], $request->get('remember'))) {
}
/** Front Guard **/
if (Auth::guard('front')->attempt(['username' => $credentials['username'], 'password' => $credentials['password']], $request->get('remember'))) {
}

  1. Finally add the Guard in sanctum.php
'guard' => ['front','web']
Sanaulla
  • 1,329
  • 14
  • 13
0

Defining API sanctum guards using the sanctum driver

'guards' => [
        // Web Guards
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        //API Sanctum Guards
        'admin-api' => [
            'driver' => 'sanctum',
            'provider' => 'admins',
        ],
        'vendor-api' => [
            'driver' => 'sanctum',
            'provider' => 'vendors',
        ],
    ],

Defining Providers

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],
    'admins' => [
        'driver' => 'eloquent',
        'model' => App\Models\Admin::class,
    ],
    'vendors' => [
        'driver' => 'eloquent',
        'model' => App\Models\Vendor::class,
    ],
],

Generating Token

$user = Admin::where('email', $request->email)->first();
$token = $user->createToken(uniqid());
return ['token' => $token->plainTextToken];


$user = Vendor::where('email', $request->email)->first();
$token = $user->createToken(uniqid());
return ['token' => $token->plainTextToken];

Protecting Routes using sanctum guard

Route::middleware('auth:admin-api')->get('/admin', function (Request $request) {
    return $request->user();
});

Route::middleware('auth:vendor-api')->get('/vendor', function (Request $request) {
    return $request->user();
});
Dhairya Lakhera
  • 4,445
  • 3
  • 35
  • 62
-1

I think the default guard should be like this:

'defaults'{
    'guard' : "sanctum_admin",
    'passwords': 'admins',
}

Or

'defaults'{
    'guard' : 'web',
    'passwords' : 'users',
}
David Buck
  • 3,752
  • 35
  • 31
  • 35
Nadir
  • 1