Sage One API - unsupported_grant_type

我正在尝试按照 文档 使用 Guzzle (v6) / Laravel 5.2 (Laravel 对此问题不相关),获取 Sage One API 的访问令牌,但卡在"请求访问令牌"阶段。

错误

客户端错误:`POST https://api.sageone.com/oauth2/token`的响应为
 `400 Bad Request`:{"error":"unsupported_grant_type"}

问题代码

    $client = new Client([
        'base_uri'=>'https://api.sageone.com',
        'headers' => ['content_type' => 'application/x-www-form-urlencoded']
    ]);
    $data = [
        'client_id' => getenv('SAGE_CLIENT'),
        'client_secret' => getenv('SAGE_SECRET'),
        'code' => $request->code,
        'grant_type' => 'authorization_code',
        'redirect_uri'=>'https://myurl.com/sage/refresh'
    ];

    $response = $client->request('POST','/oauth2/token',['json' => $data]);

文档中说明了 **_"grant_type - 代码所涉及的授权类型。授权码或刷新令牌。"_**,我尝试了两种方式。其他变量都是正常可行的,但是 grant_type 看起来是不行的。

更新1 调试头文件生成以下输出。

* Hostname in DNS cache was stale, zapped * Trying 52.49.116.133...
* Connected to api.sageone.com (52.49.116.133) port 443 (#0)
* CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none
* ALPN/NPN, server did not agree to a protocol
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* subject: CN=api.sageone.com,O=The Sage Group PLC,L=Newcastle Upon Tyne,ST=Newcastle Upon Tyne,C=GB,serialNumber=02231246,businessCategory=Private Organization,incorporationCountry=GB
* start date: May 12 00:00:00 2014 GMT
* expire date: May 11 23:59:59 2016 GMT
* common name: api.sageone.com
* issuer: CN=GeoTrust Extended Validation SSL CA - G2,O=GeoTrust Inc.,C=US > POST /oauth2/token HTTP/1.1 Host: api.sageone.com content_type: application/x-www-form-urlencoded User-Agent: GuzzleHttp/6.1.1 curl/7.43.0 PHP/5.6.18 Content-Type: application/x-www-form-urlencoded Content-Length: 216
* upload completely sent off: 216 out of 216 bytes < HTTP/1.1 400 Bad Request < Content-Type: application/json < Date: Tue, 08 Mar 2016 10:53:09 GMT < Server: openresty < Content-Length: 26 < Connection: keep-alive <
* Connection #0 to host api.sageone.com left intact
点赞
用户3748349
用户3748349

你正在以 JSON 编码的数据 POST 值,但是你应该以表单编码 POST。参见:http://docs.guzzlephp.org/en/latest/request-options.html#form-params,因此,

$response = $client->request('POST','/oauth2/token',['form_params' => $data]);

编辑:

你应该再次检查你的代码,因为我刚刚验证和核实了这一变化在实时的 sage 环境中可以正常工作。我使用的完整代码:

<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client([
        'base_uri'=>'https://api.sageone.com',
        'headers' => ['content_type' => 'application/x-www-form-urlencoded']
    ]);

$data = [
    'client_id' => getenv('SAGE_CLIENT'),
    'client_secret' => getenv('SAGE_SECRET'),
    'code' => getenv('SAGE_CODE'),
    'grant_type' => 'authorization_code',
    'redirect_uri'=>'https://myurl.com/sage/refresh'
];

$response = $client->request('POST','/oauth2/token',['form_params' => $data]);

echo $response->getBody();

?>
2016-03-08 10:13:25
用户4621324
用户4621324

将 JSON 用于 oAuth 真的是不正确的:https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3

我认为这是不正确的:

$response = $client->request('POST','/oauth2/token',['json' => json_encode($data)]);

相反,我会尝试这个:

$response = $client->post('/oauth2/token', [], $data);

或者这个

$response = $client->post('/oauth2/token', ['body' => $data]);

另外一个问题,第一个调用 https://www.sageone.com/oauth2/auth - 是否已经通过了?

2016-03-13 18:45:10