使用 Laravel Passport 获取经过身份验证的用户并授予密码

Posted

技术标签:

【中文标题】使用 Laravel Passport 获取经过身份验证的用户并授予密码【英文标题】:Get authenticated user with Laravel Passport and grant password 【发布时间】:2017-06-19 05:55:39 【问题描述】:

我用 Laravel 做了一个 API REST,现在我正在尝试使用它。问题是我需要在 API 中对用户进行身份验证,并且我正在使用 Password Grant 方法。我可以正确地对用户进行身份验证,并且可以获得访问令牌,但从那时起,我看不到在我的消费应用程序中使用访问令牌检索经过身份验证的用户的方法。

我在 API 中尝试了这样的路由:

Route::get('/user', function(Request $request) 
    $user = $request->user();
    // Even with
    $user = Auth::user();

    return $user;
);

没有骰子。我正在阅读护照代码,但我无法弄清楚。我的猜测是我需要指定一个新的保护类型或其他东西,因为 Laravel Passport 似乎没有为这种授权类型提供一个......

澄清一下:

我有一个 API REST 应用程序,即 oAuth2 服务器。 我有另一个使用 API REST 的应用程序。 我知道工作流程。在我的情况下,通过密码授予,我在我的消费者应用程序中获取用户凭据,然后我向 /oauth/token 发出请求,指定 grant_typepassword,我提供用户凭据以及我的客户端凭据,我确信它们是使用“php artisan passport:client --password”生成的(注意 --password 选项) 我可以毫无问题地获得访问令牌。我现在需要的是获取我刚刚从 API REST 进行身份验证的用户的 JSON 表示。但问题是:我只有一个访问令牌。我无法与用户产生任何联系。

或者我可以吗?也许我可以扩展验证密码授予请求的方法,以将生成的访问令牌与它正在验证的用户相关联... *灯泡打开*

消费应用测试代码:

try 
    $client = new Client();
    $result = $client->post('https://myapi.com/oauth/token', [
        'form_params' => [
            'grant_type' => 'password',
            'client_id' => '5',
            'client_secret' => 'my_secret',
            'username' => 'user_I_am_authenticating',
            'password' => 'the_user_password',
            'scope' => '',
        ]
    ]);
    $access_token = json_decode((string) $result->getBody(), true)['access_token'];
    $result = $client->get('https://myapi.com/client/user', [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
            'Authorization' => "Bearer $access_token",
        ]
    ]);

    return (string) $result->getBody();
 catch (GuzzleException $e) 
    return "Exception!: " . $e->getMessage();

请注意,https://myapi.com/client/user 路由只是我为在 API 中测试而制作的路由。该路线定义为:

Route::get('/user', function(Request $request) 
    return $request->user();
);

现在。我知道这行不通。这就是我想要实现的。根据 access_token/bearer_token 了解发出请求的用户。

【问题讨论】:

您会添加客户端代码和收到的错误吗?是 404 吗? 我可以添加代码。但正如我所说,我没有任何错误。我向我想要的 API 中的任何路由发出请求,问题是在我的 API 路由中,我想知道客户端代表哪个用户发出请求。 你的意思是,你想知道登录用户? 是的。消费应用程序正在使用类似于 client_credentials 的授权类型。这意味着应用程序代表它自己发出请求。但是对于用户来说,有授权方法,还有密码授予。这些代表授权用户提出请求。 我找到了一个简单的解决方案,但不确定它是否是正确的方法...将您的路线 /user 包裹在一个组中 middleware => ['web', 'auth:api'] 【参考方案1】:

您忘记了适当的中间件。

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

当您不提及 auth 中间件时,不会触发身份验证流程。这就是你得到null的原因。

【讨论】:

但是如果身份验证是可选的会发生什么。即经过身份验证的用户会看到这个,而未经身份验证的用户会看到其他内容【参考方案2】:

我和你有同样的问题。我在手动定义身份验证保护后解决了它。

Route::get('/user', function (Request $request) 
  return auth()->guard('api')->user();
);

【讨论】:

【参考方案3】:

您需要将访问令牌与每个请求一起传回。请查看此部分的文档here

【讨论】:

以上是关于使用 Laravel Passport 获取经过身份验证的用户并授予密码的主要内容,如果未能解决你的问题,请参考以下文章

使用 Laravel Passport 获取经过身份验证的用户并授予密码

Laravel Passport API:检索经过身份验证的令牌

Laravel Passport 没有身份验证

Laravel Passport尝试获取非对象的属性“秘密”

Nuxtjs + Laravel Echo + Laravel Passport + Laravel WebSockets 无法从私人/状态通道获取事件

Laravel7 Passport:尝试将请求发送到“api/user”时获取“未定义索引:aud”