Laravel Passport密码授予 - 客户端身份验证失败

Kan*_*nav 23 php oauth laravel laravel-5.3

在听了很多关于laravel护照之后,我想到将它实现到我的新项目中,我的要求是创建一个将在移动应用中使用的API.

所以我的移动应用程序是一个client,它将进一步拥有其用户.

我按照泰勒提到的步骤进行了阅读,并在此处阅读了相关内容.简而言之,我遵循了以下步骤:

  1. 已安装laravel/passport.
  2. 创建了一个网站用户.
  3. 生成的护照钥匙 php artisan passport:install
  4. 生成client_idclient_secret使用php artisan passport:client
  5. 添加redirectioncallback路由web.php
  6. 授权用户并获得最终访问令牌.

然后我尝试调用api/user(包含Header Authorization包含值Bearer eyJ0eXAiOiJKV1...(token)

我收到了数据.非常简单而整洁.

但我的应用用户将不会有这些详细信息.所以我想到配置密码授予令牌,完全符合我的要求.

现在开始真正的头痛.我一直试图在过去3天内设置这个并不断获得

{"error":"invalid_client","message":"Client authentication failed"}
Run Code Online (Sandbox Code Playgroud)

我几乎尝试了我在网上关注的所有指南:重定向问题,添加Atleast One Scope解决方案,P100Y问题等.

但我仍然得到invalid client错误.这是我通过POSTMAN传递给的oauth/token:

{
    "grant_type": "password,"
    "client_id": "3,"
    "client_secret": "8BUPCSyYEdsgtZFnD6bFG6eg7MKuuKJHLsdW0k6g,"
    "username": "test@gmail.com,"
    "password": "123456,"
    "scope": ""
}
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激.

Sha*_*ikh 15

首先检查您的凭据是否正确,然后检查您的模型表使用的\Laravel\Passport\HasApiTokens特征是否包含email列,因为默认情况下它用于在验证凭据时识别用户.如果您的表具有username列或用于验证凭据的任何其他列,则必须findForPassport在该模型中定义函数.像这样,

public function findForPassport($username) {
       return self::where('username', $username)->first(); // change column name whatever you use in credentials
    }
Run Code Online (Sandbox Code Playgroud)

我使用用户名和密码列来验证用户 {project_directory}\vendor\laravel\passport\src\Bridge\UserRepository.php

此功能验证您的凭据,

public function getUserEntityByUserCredentials($username, $password, $grantType, ClientEntityInterface $clientEntity)
    {
        if (is_null($model = config('auth.providers.users.model'))) {
            throw new RuntimeException('Unable to determine user model from configuration.');
        }

        if (method_exists($model, 'findForPassport')) { // if you define the method in that model it will grab it from there other wise use email as key 
            $user = (new $model)->findForPassport($username);
        } else {
            $user = (new $model)->where('email', $username)->first();
        }

        if (! $user || ! $this->hasher->check($password, $user->password)) {
            return;
        }

        return new User($user->getAuthIdentifier());
    }
Run Code Online (Sandbox Code Playgroud)

注意第二个if语句,你就会知道那里发生了什么.

希望这个帮助:)

  • 您确定要传递的client_id是密码授予客户端吗?即password_client列在oauth_clients表中的值为1. (5认同)
  • `php artisan Passport:client --password`运行它。 (3认同)

And*_* F. 10

这可能有助于指明您正确的方向,因为我们自己正在实施密码授权.

1 - 在第4步而不是运行:

php artisan passport:install
Run Code Online (Sandbox Code Playgroud)

运行以下命令以创建密码授予客户端:

php artisan passport:client --password
Run Code Online (Sandbox Code Playgroud)

上面的命令将给出一个后续问题来设置密码授予客户端的名称.请务必在数据库中获取此新记录的ID和密码.

2 - 您的POSTMAN Post请求对象应该包含在类似于以下内容的对象中:

'form_params' => [
    'grant_type' => 'password',
    'client_id' => 'my_client-id',
    'client_secret' => 'my_client-secret',
    'username' => 'username or email', <-pass through variables or something
    'password' => 'my-user-password', <- pass through variables or something
    'scope' => '',
],
Run Code Online (Sandbox Code Playgroud)

2016年10月10日更新:

在对这个问题的进一步调查中,我遇到了你所处的完全相同的位置,并被迫潜入护照的兔子洞.

目前,根据我所看到的,系统在需要"密码"时将客户端标识符设置为"authorization_code".我正在研究如何解决你遇到的这个问题,因为我也遇到过这个问题.我会发布代码,以帮助人们跟随我去过的地方以及我一直在做的事情,但现在是凌晨2点40分,所以我需要一些睡眠.

2016年10月10日更新

现在已经调试了7个小时的问题.护照内有一种方法可以验证客户.此方法接受您在对象中添加的输入(如上所述),并尝试根据您传入的内容通过客户端存储库类获取客户端实体.如果找到客户端,则会检查它是否会检查客户端实体的一个实例确实存在于客户端实体接口中,它看起来像是从数据库中提取客户端的凭据.但是,有一段代码返回NULL从我在测试中获得的内容.到目前为止,所有字段都被正确引入,但是存储库和接口之间似乎存在混淆.这导致错误被抛出.

最后我觉得我已经接近解决这个问题了.非常感谢您的耐心等待.=)

2016年10月10日更新

经过长时间的调试后,我发现了最初的问题.有些字段没有匹配.简而言之,这是一个设置问题.

所以

这种情况下的解决方案是:

仔细检查各个领域在数据库所有的凭据传递一直到句点,破折号,空格口令,客户端ID,客户端密钥,有效的重定向的URI /网址,grant_types和范围(如果你使用它们):

确保数据库中的客户端在"password_client"列下的ENUM为1,如果不是,则需要使用上面提到的php artisan命令创建一个,我将在此处引用:

php artisan passport:client --password
Run Code Online (Sandbox Code Playgroud)

确保您传入的秘密与数据库角色中为该角色列出的内容相匹配

确保您传递的id匹配并且是整数数据类型.

确保客户端有某种名称

使用密码授予时,请不要担心user_id列

确保路线正确

确保您输入的用户名(用户名)是数据库中用户表内的实际用户(或者您自定义laravel 5.3系统作为用户表接受的任何表,我将添加有关如何自定义laravel 5.3的链接系统接受不同的用户表作为默认值,如果有需要的话).

确保grant_type拼写正确

确保您已设置为接受响应承载令牌(表示access_token和refresh_token).

除此之外,我在本答案的上述部分中概述的初始步骤应该让您回到正确的轨道上.这里还有其他人提到了一些有用的类似步骤,但也解决了与单独问题相关的相同错误(我确信这是与其特定系统设置相关的设置问题的结果).

我希望这会有所帮助.


Emi*_*íaz 7

您是否尝试php artisan config:cache在所有通行证命令之后运行。