方法 Laravel\Passport\Guards\TokenGuard::attempt 不存在

问题描述 投票:0回答:4

在 Laravel 9 中,我尝试使用自定义防护来访问登录 API

client
,我收到以下错误。请帮忙。

BadMethodCallException: Method Laravel\Passport\Guards\TokenGuard::attempt does not exist.

配置/Auth.php

    'guards' => [
        ...
        'client' => [
            'driver' => 'passport',
            'provider' => 'client',
        ],
    ],

    'providers' => [
        ...
        'client' => [
            'driver' => 'eloquent',
            'model' => App\Models\Client::class,
        ],
    ],

错误行:

if(!$authGuard->attempt($login)){

api/AuthController.php

public function login(Request $request){
        $login = $request->validate([
            'email' => 'required|string',
            'password' => 'required|string',
        ]);
        try {
            $authGuard = Auth::guard('client');
            if(!$authGuard->attempt($login)){
                $data = 'Invalid Login Credentials';
                $code = 401;
            } else {
                $user = $authGuard->user();
                $token = $user->createToken('user')->accessToken;
                $code = 200;
                $data = [
                    'user' => $user,
                    'token' => $token,
                ];
            }
        } catch (Exception $e) {
            $data = ['error' => $e->getMessage()];
        }
        return response()->json($data, $code);
    }

模型/Client.php

use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;
class Client extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

截图:

php laravel laravel-passport laravel-9
4个回答
2
投票

我认为

Auth::attempt()
与护照不兼容。

所以,你可以使用

Auth::check()
方法来代替。


2
投票

attempt() 仅适用于实现 StatefulGuard 接口的守卫。

所以我同意约翰的观点,即尝试与 Passport 不兼容。

你可以尝试一下,它应该可以工作:

auth()->guard('client')->setUser($login);
Auth::guard('client')->setUser($login);


1
投票

我通过将

passport
 中的驱动程序从 
session
 更改为 
config/auth.php

解决了这个问题
'clients' => [
    'driver' => 'session',
    'provider' => 'clients',
],

我不确定这是正确的解决方案,但它有效。

如果有更好的解决方案请随时发布答案

谢谢


0
投票

Laravel Passport 似乎不支持这种类型的身份验证样式,我为解决这个问题所做的有点奇怪,但它有效。 我为所有用户模型类型创建了一个端点,如下所示:

 Route::post('auth/{user_type}/login', [AuthController::class, 'login']);

然后我添加了一个辅助函数来获取我希望进行身份验证的用户模型:

function resolve_user_type(string $user_type) 
{
    return match ($user_type) {
        'user'=> User::class,
        'admin'=> Admin::class,
        default => throw new InvalidArgumentException()
    };
}

然后我修改了你的登录方法:

public function login(Request $request , $user_type)
{
    $model = resolve_user_type($user_type);
    $login = $request->validate([
        'email' => 'required|email',
        'password' => 'required|string',
    ]);
    try {
        $user = $model::whereEmail($login['email'])->first();

        if (!$user || !Hash::check($login['password'], $user->password)) {
            $data = 'Invalid Login Credentials';
            $code = 401;
        } else {

            $token = $user->createToken('authToken', [$user_type])->accessToken;
            $code = 200;
            $data = [
                'user' => $user,
                'token' => $token,
            ];
        }
    } catch (Exception $e) {
        $data = ['error' => $e->getMessage()];
    }
    return response()->json($data, $code);
} 

其中方法 createToken() 中的第二个参数是我为用户令牌创建的范围的名称,并在启动方法的 AuthServiceProvider 文件中定义它:

Passport::tokensCan([
        'user'=>'user',
        'admin'=>'admin'
    ]);

这对于我来说足够动态,可以使用并继续前进,但请记住这三个必须相同:

  • 用户输入路线
  • 令牌范围内的用户类型
  • 用户在帮助函数中输入
© www.soinside.com 2019 - 2024. All rights reserved.