2016-09-19 115 views
13

听到很多关于laravel护照的信息后,我想到将其实施到我的新项目中,我的要求是创建一个将用于移动应用程序的API。Laravel Passport Password Grant - 客户端身份验证失败

所以我的移动应用程序是client,这将进一步有其用户。

我按照步骤mentioned by Taylor并且还读了关于它here。简而言之,我遵循以下步骤:

  1. 安装laravel/passport
  2. 创建网站用户。
  3. 使用php artisan passport:client
  4. 新增redirectioncallback航线web.php
  5. 产生的护照键php artisan passport:install
  6. 生成client_idclient_secret授权用户,并得到了最终的访问令牌。

然后我打过电话api/user(用头Authorization含价值Bearer eyJ0eXAiOiJKV1...(token)

我接收到的数据。很简单利落。

但我的应用程序的用户将不会有这些细节,所以我想配置Password Grant Tokens这完全符合我的要求

现在开始真正的头痛,我一直试图设置过去3天,并不断得到

{"error":"invalid_client","message":"Client authentication failed"} 

我已经试过几乎所有的导游,我在网上其次:Redirection IssuesAdd Atleast One Scope SolutionP100Y Issue

但我仍然得到invalid client错误。这是我通过POSTMAN通过oauth/token

{ 
    "grant_type": "password," 
    "client_id": "3," 
    "client_secret": "8BUPCSyYEdsgtZFnD6bFG6eg7MKuuKJHLsdW0k6g," 
    "username": "[email protected]," 
    "password": "123456," 
    "scope": "" 
} 

任何帮助,将不胜感激。

+0

进入你尝试范围:“*”老实说,我一直都停留在同样的事情过去的一天,以及... –

+0

是的,我做到了。同样的结果 – Kanav

+4

讨厌说明明显,但看起来你的对象不是一个有效的JSON,请检查你的逗号 – sam1188

回答

9

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

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

我使用用户名和密码栏,以验证用户, 在{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()); 
    } 

通知第二if语句,你会得到知道那里发生了什么。

希望这有助于:)

+0

我没有使用用户名。 – Kanav

+2

您确定您传递的client_id是密码授权客户端吗?即在oauth_clients表中password_client列的值为1。 –

+0

对于我来说,该特定客户端的'password_client'列值是'0'。我手动将其更改为“1”,但没有帮助。 – Kanav

1

我有同样的问题,找来通过设置basic.auth头文件,如CLIENT_ID用户名和密码口令固定。

然后它工作正常。

+0

仍然没有工作 – Kanav

0

我设法让Laravel Passport - Password_Grant_Token通过RESTED(POSTMAN就像服务)工作,没有任何额外的控制器或中间件。这是我设法做到的!

在laravel doc's here
安装默认的认证,脚手架安装护照doc's here
通过AUTH-脚手架
转到注册用户休息或邮递员,或任何其他类似的服务在oauth_clients表
检查数据为您form_params
RESTED through Request_body_form_data not headers写你的forms_params并发送POST请求到*/oauth/token(需要完整url)

(必需的form_params是grant_type,client_id,client_secret,用户名和密码)

您应该返回一个包含4个键(token_type,expires_in,access_token & refresh_token)和200 OK状态的对象。

如果一切是succesfull那么远,

打开另一个窗口休息:

发送GET请求/ API /用户(需要再次完整的网址) 在标题写2名 - 值对(接受=>应用程序/ JSON,授权=>承载ACCESS_TOKEN_GOTTEN_IN_PREVIOUS_REQUEST(到/的OAuth /令牌)

这应该是它。你应该得到一个用户对象从/ API /用户响应。

+0

我试着发送它两种方式:'form-data'和'x-www-form-encoded'。得到了相同的结果 – Kanav

1

尝试肌酸g使用php工匠护照的新密码客户端:客户端 - 密码 那么很可能用户不会被分配到该密码客户端。编辑数据库行并为其添加一个exsting用户标识。

{ 
    "grant_type": "password," 
    "client_id": "" <- edited and added user id 
    "client_secret": "8BU......," <- new secret 
    "username": "[email protected]," <- email of above added user id 
    "password": "123456,"<- password 
    "scope": "" 
} 

希望你能够得到令牌现在

+0

我试过了你的建议,结果仍然一样。 =/ –

4

这可能有助于一点,你在正确的方向,因为我们正在实施的密码授予自己。

1 - 关于你的第4步,而不是运行此:

php artisan passport:install 

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

php artisan passport:client --password 

上面的命令将给予后续问题设置您的密码授予客户端的名称。一定要在数据库中获得这个新记录的ID和秘密。

'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' => '', 
], 

更新1 2016年10月12日: -

2你邮差发布采购对象应类似于下面的物体内部包裹

在这个问题上的进一步调查中,我遇到了同样的地点,并被迫进入护照的兔子洞。

目前从我所看到的系统已设置客户端标识符为'authorization_code',当它需要'密码'。我正在研究如何解决您遇到的问题,因为我也遇到了这个问题。我会发布代码来帮助人们跟随我去过的地方以及我一直在做的事情,但现在是凌晨2:40,所以我需要一些睡眠。

更新2 2016年10月12日

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

最后我觉得我正在接近解决这个问题。非常感谢您的耐心。 =)

更新3 2016年10月12日

后调试长时间我发现最初的问题。有些字段不匹配。总之,这是一个设置问题。

SO

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

仔细检查所有字段ALL凭据传递的数据库一直到句点,破折号,空格口令,客户端ID。 ,客户端密码,VALID重定向URIs/URLs,grant_types和作用域(如果您正在使用它们):

确保数据库中的客户端在“password_client”列下的ENUM为1,如果不是,您需要用我来创造一个ntioned PHP的工匠上面的命令,我会在这里引用:

php artisan passport:client --password 

确保你传递什么列出该客户端数据库中的字符的字符匹配的秘密

确保ID您传递的是匹配,并且是整数数据类型。

确保有使用口令授予时

确保路线是正确的

确保电子邮件

不要对user_id列担心某种客户端的名字你输入(用户名)是数据库内用户表内的实际用户(或任何您定制的laravel 5.3系统作为用户表接受的表),我将添加一个关于如何定制laravel 5.3系统以接受不同的用户表作为默认值,如果有需要的话)。

确保grant_type正确

拼写确保您设置为接受承载令牌响应(指和的access_token refresh_token)。

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

我希望这有助于。

+0

是的,一群人正面临着这个问题。让我知道如果你找到一个解决方案 – Kanav

+0

请参阅更新2 10/12/2016 –

+0

请参阅更新3的答案。仔细阅读 –

0

在护照服务器上设置客户端时检查重定向/回调URL。检查您获得客户端ID和密钥的条目,重定向URL是否正确。

我得到相同的错误,发现重定向URL不正确。

它需要指向/回调路径(在泰勒给出的例子)

0
{"error":"invalid_client","message":"Client authentication failed"} 

意味着,CLIENT_ID和client_secret您当前正在发送的是下列之一:

  1. CLIENT_ID和client_secret发送是不是在您的OAuth服务器
  2. CLIENT_ID注册和client_secret发送是不您在帖子正文

对于我指定授权类型的,针对特定的客户端 的password_client列的值是0。我是手动更改为1,但它并没有帮助。 - Kanav 10月4日在 3时25

当我读到您的评论的一些答案,使这一个是显而易见的,你使用了错误的类型CLIENT_ID和client_secret为您的密码补助流,所以你的情况是后者。您可以通过寻找oauth_clients表中的条目为您提供的client_id验证和client_secret

"grant_type": "password,"  
"client_id": "3," 
"client_secret": "8BUPCSyYEdsgtZFnD6bFG6eg7MKuuKJHLsdW0k6g," 

SELECT * FROM oauth_clients WHERE id = 3 AND secret = '8BUPCSyYEdsgtZFnD6bFG6eg7MKuuKJHLsdW0k6g' AND password_client=1; 

在oauth_clients表,查看是否您提供的client_id和client_secret 存在于您的OAuth服务器密码补助流。而且您也不需要通过简单地切换该列的值来手动更改客户端的类型,您必须为密码授权类型创建新的客户端

php artisan migrate 

此命令将迁移laravel /护照迁移文件生成两个默认客户的每类laravel /护照目前支持。您还可以创建密码补助流客户端

php artisan passport:client --password 

当你有密码补助类型的新客户端,请尝试重新发布到/的OAuth /令牌生成新生成的client_id令牌和client_secret

0

在所有护照命令之后,您是否尝试运行php artisan config:cache

0

使用下面的代码来生成一个访问令牌,它已经为我面前:

$request->request->add([ 
     'client_id' => '2', 
     'client_secret' => 'm3KtgNAKxq6Cm1WC6cDAXwR0nj3uPMxoRn3Ifr8L', 
     'grant_type' => 'password', 
     'username' => '[email protected]', 
     'password' => 'pass22' 
    ]); 
    $tokenRequest = $request->create('/oauth/token', 'POST', $request->all()); 

    $token = \Route::dispatch($tokenRequest); 
0

你可以这样定义

$client_id = '111'; 
$client_secret = '1212'; 

两个变量和条件是你的功能一样

protected $clientID = '578324956347895'; 
protected $clinetSecret ='hflieryt478'; 

public function index(Request $request) 
{ 

    if (!($request->input('clientID') && $request->input('clinetSecret'))) { 
     return false; 
    } 

    $project = User::all(); 

    return $project 
} 
0

彻底检查授权类型。

{ 
    "grant_type": "password", 
    "client_id": 2, 
    "client_secret": 
    "username": , 
    "password": 
    "scope": "" 
} 

在上面的例子中,它表示密码。现在,检查表:oauth_clients 并确保列password_client = 1

或值查找与password_client = 1