Oauth 2.0 对Feedly API的授权请求引发了错误的Guzzle请求?

Oauth 2.0 对Feedly API的授权请求引发了错误的Guzzle请求?,oauth-2.0,authorization,guzzle,feedly,Oauth 2.0,Authorization,Guzzle,Feedly,目标是交换访问和刷新令牌的授权代码 错误: GuzzleHttp\Exception\ClientException #400 Client error response [url] http://sandbox.feedly.com/v3/auth/token?code=[auth_code]&client_id=sandbox&client_secret=[secret]&redirect_uri=https%253A%252F%252F[site url]&am

目标是交换访问和刷新令牌的授权代码

错误:

GuzzleHttp\Exception\ClientException #400

Client error response 
[url] http://sandbox.feedly.com/v3/auth/token?code=[auth_code]&client_id=sandbox&client_secret=[secret]&redirect_uri=https%253A%252F%252F[site url]&grant_type=authorization_code&state=%23 
[status code] 400 
[reason phrase] Bad Request
相关代码:

$client = new GuzzleHttp\Client();
$parameters = ['code'=>$_GET['code'],'client_id'=>'sandbox','client_secret'=> '[secret]','redirect_uri'=>urlencode('https://[site url]'),'grant_type'=>'authorization_code', 'state'=>'#'];
$params = http_build_query($parameters);
$request = $client->createRequest('POST', 'http://sandbox.feedly.com/v3/auth/token?'.$params);
$request->addHeader('Accept-Encoding','GZIP');
$request->setHeader('Authorization', "auth-code");
$request->addHeader('Content-Type','application/json');
$response = $client->send($request);
var_dump($response->json());
在“中也尝试了
state=“state.passed.in”,但抛出相同的错误

你能指出代码片段中的错误吗。它使用Feedly API v3沙箱和Guzzle HTTP客户端

如果遵循请求URL,则抛出“get not allowed”

更新的代码片段:

$client = new GuzzleHttp\Client();
    $parameters = ['code'=>$_GET['code'],'client_id'=>'sandbox','client_secret'=> '[secret]','redirect_uri'=>urlencode('https://[site url]'),'grant_type'=>'authorization_code', 'state'=>'#'];
    $params = http_build_query($parameters);
    $request = $client->createRequest('POST', 'http://sandbox.feedly.com/v3/auth/token?'.$params);
    $response = $client->send($request);
    var_dump($response->json());
GuzzleHttp\Exception\ServerException #522

Server error response [url] http://sandbox.feedly.com/v3/auth/token?code=[auth_code]&client_id=sandbox&client_secret=[secret]&redirect_uri=https%253A%252F%252F[site url]&grant_type=authorization_code&state=%23 
[status code] 522 
[reason phrase] Origin Connection Time-out  
更新代码时出错:

$client = new GuzzleHttp\Client();
    $parameters = ['code'=>$_GET['code'],'client_id'=>'sandbox','client_secret'=> '[secret]','redirect_uri'=>urlencode('https://[site url]'),'grant_type'=>'authorization_code', 'state'=>'#'];
    $params = http_build_query($parameters);
    $request = $client->createRequest('POST', 'http://sandbox.feedly.com/v3/auth/token?'.$params);
    $response = $client->send($request);
    var_dump($response->json());
GuzzleHttp\Exception\ServerException #522

Server error response [url] http://sandbox.feedly.com/v3/auth/token?code=[auth_code]&client_id=sandbox&client_secret=[secret]&redirect_uri=https%253A%252F%252F[site url]&grant_type=authorization_code&state=%23 
[status code] 522 
[reason phrase] Origin Connection Time-out  
注意:更新代码抛出的错误(几小时后)与

GuzzleHttp\Exception\ClientException #400

Client error response 
[url] http://sandbox.feedly.com/v3/auth/token?code=[auth_code]&client_id=sandbox&client_secret=[secret]&redirect_uri=https%253A%252F%252F[site url]&grant_type=authorization_code&state=%23 
[status code] 400 
[reason phrase] Bad Request

根据OAuth 2.0规范,从底部开始:

客户端在创建访问令牌时必须使用HTTP“POST”方法 请求

(来源:第3.2节。)

因此,这解释了为什么在浏览器中导航到请求URL会失败(导航发出
GET
,并且只支持
POST
请求)

下一点是客户端身份验证,更具体地说,是如何提供
client\u id
client\u secret
参数,以便服务器可以验证您是受信任的客户端应用程序。同样,根据规范,有两种方式可以传递此信息:

  • 通过[RFC2617]中定义的HTTP基本身份验证方案,其中客户端标识符作为用户名传递,客户端密码作为密码传递。此方法必须由符合OAuth的服务器支持,并且也是推荐的方法。*
  • 通过在请求正文中包含客户端凭据,通常编码为
    application/x-www-form-urlencoded
    (参见下面的示例)。此方法是可选的,在某些OAuth服务器中可能不可用
  • 在请求正文中传递客户端凭据的示例:

    POST https://YOUR_NAMESPACE/oauth/token
     Content-type: application/x-www-form-urlencoded
    
    client_id=YOUR_CLIENT_ID
    &redirect_uri=http://YOUR_APP/callback
    &client_secret=YOUR_CLIENT_SECRET
    &code=AUTHORIZATION_CODE
    &grant_type=authorization_code
    
    (来源:的第四步,单击第二步中的普通链接以查看完整授权代码授权流中的所有原始HTTP请求)

    现在,对于Feedly用例,我在那里的文档中找不到任何关于支持HTTP基本身份验证的内容。他们确实说明了将代码交换为访问令牌所需的参数:

    注意:这些参数可以作为表单值在URL中传递,也可以在JSON文档中传递。如果使用JSON文档,请确保在请求中传递“Content-Type:application/JSON”头

    (来源:)

    令人惊讶的是,它们似乎允许在URL本身中传递客户端凭据,这是OAuth规范明确禁止的:

    参数(client_id和client_secret)只能在请求正文中传输,不能包含在 请求URI

    (来源:第2.3.1节。)

    总之,根据他们的文档,您所做的(在URL本身中传递参数)应该是可能的,除非文档不是最新的,并且他们已经修复了不符合规范的问题,并且不再支持这一点

    此外,你所做的事情很少有错误的地方。
    code
    参数永远不会在
    authorization
    头中传递,因此除非您想尝试使用基本身份验证在该头中传递客户端凭据,否则我建议您删除此头

    我还将删除
    Accept Encoding
    标题,因为他们的文档除了返回JSON响应外,没有提到支持任何东西。如果要维护该标题,请将值从
    gzip
    更改为
    application/json


    最后,您也没有在请求正文中发送任何数据,因此,您可能还需要删除
    内容类型
    标头,因为Feedly可能会认为,如果存在此标头,则数据位于请求上,而不是URL上。

    问题:重定向URI是双重编码的,即我正在传递
    https%253A%252F%252Fdev10.ritepush.com%252Fdashboard
    ,它解码为https%3A%2F%2Fdev10.ritepush.com%2fmdashboard
    。我必须对uri编码一次,这是我需要传递的
    https%3A%2F%2Fdev10.ritepush.com%2fmdashboard

    原因:PHP自动对http请求进行编码,因此在将
    urlencode
    应用于
    重定向uri
    时,我实际上对重定向uri进行了两次编码,但只解码了一次。因此,在请求主体中传递编码URI,从而导致错误


    感谢Feedly的David Chatenay指出了错误。

    522状态代码不是标准的,我知道CloudFare使用它来表示服务器连接超时,因此这可能是Feedly服务器上的问题。谢谢你的解释。这很有帮助。我适当地更新了代码,并收到
    [状态代码]522[原因短语]源站连接超时错误
    。我在问题中添加了更新的代码和错误。我仔细查看了错误的详细信息,发现这是一个服务器端错误。你能解释一下这个错误吗?是否有一些修正(以防我遗漏了什么)可以从我这边申请?更新后的代码出现了相同的错误:
    [status code]400[reason phrase]错误请求
    ,在尝试了几个小时之后。522错误现在没有出现。你能解释一下这个问题吗?