Reputation: 644
I am trying multiguard authentication for api when i login for admin i am getting following error
BadMethodCallException Method Illuminate\Auth\Req uestGuard::attempt does not exist.
here is my login method in controller
public function login(Request $request){
if(Auth::guard('admin-api')->attempt(['email' => request('email'), 'password' => request('password')]))
{
// if successful, then redirect to their intended location
$user = Auth::guard('admin-api');
$success['token'] = $user->createToken('admin')->accessToken;
return response()->json(['success' => $success], $this->successStatus);
}
else{
return response()->json(['error'=>'Unauthorised'], 401);
}
}
my api.php
Route::prefix('admin')->group(function () {
Route::post('login', 'API\Admin\AdminController@login')->name('admin.login');
Route::post('register', 'API\Admin\AdminController@register')->name('admin.register');
Route::group(['middleware' => 'auth:admin-api'], function(){
Route::post('get-details', 'API\Admin\AdminController@getDetails');
});
});
my admin model
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;
class Admin extends Authenticatable
{
use HasApiTokens, Notifiable;
protected $table = 'admin';
protected $guard = 'admin-api';
/**
* 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',
];
}
please tell me any other inputs you want
Upvotes: 3
Views: 15256
Reputation: 133
you cannot use Auth::guard('admin-api')->attempt with a guard with driver value is token or passport so you can repeat the guard and make one with session driver and the second one with passport then you can use the session one to make difference between earch other you can see a reference and source code from here
https://web-brackets.com/discussion/103/method-illuminate-auth-requestguard-attempt-does-not-exist-
Upvotes: 0
Reputation: 59
A better hack is this
$credentials = ['email' => $request->username, 'password' => $request->password];
//Since we are not using guard web in API request, we have to add it here (
// guard('web') ) to access the Auth::attempt function,
// the Auth::attempt needs web guard and crsf token, but using it here bypasses
// the post with crsf.
if (Auth::guard('web')->attempt($credentials, false, false)) {
dd('user is OK');
}else{
dd('user is NOT OK');
}
Upvotes: 3
Reputation: 303
To me, I changed drivers for the web from passport to session. Laravel's cache had to be cleared to be able to go back to the session driver
php artisan cache:clear
Upvotes: -2
Reputation: 697
Unfortunately the Laravel Facade for Auth does not expect you to use it for the api guard since sessions and cookies will be set, Thus does not support ->attempt()
function. But the API middle-ware disables session and cookies since it is stateless. So here is the hack.
Get to your confi\auth and create a similar web instance for your api guards thus
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'drivers-web' => [
'driver' => 'session',
'provider' => 'drivers',
],
'api' => [
'driver' => 'passport',//previously "token"
'provider' => 'users',//This will be switched regularly from the middleware between drivers and users
],
'drivers-api' => [
'driver' => 'passport',//previously "token"
'provider' => 'drivers',
],
],
Never the less, You can use passport to generate your client access tokens which are stateless sessions. And also serve well for authentication.
Upvotes: 0