eBay REST API:invalid_request 交换访问令牌的授权代码时

eBay REST API: invalid_request when exchanging the authorization code for an access token

我正在尝试通过他们的新 REST API 连接到 eBay API。

我正在使用一个非常简单的脚本来测试流程,我正在使用 Guzzle。

我关注的指南是 this

但是当需要用访问令牌交换授权码时,我收到了以下响应:

{"error":"invalid_request","error_description":"request is invalid","error_uri":null}

我真的不知道该用什么来完成这项工作。

这是我正在使用的代码:

<?php

...

if (isset($_GET['code'])) {
    $client = new \GuzzleHttp\Client();

    $authorization = base64_encode($appId . ':' . $certId);
    $code = urlencode($_GET['code']);
    $body = 'grant_type=authorization_code&code=' . $code . '&redirect_uri=' . $ruName;

    $options = [
        \GuzzleHttp\RequestOptions::HEADERS => [
            'Content-Type' => 'application/x-www-form-urlencoded',
            'Authorization' => 'Basic ' . $authorization,
        ],
        \GuzzleHttp\RequestOptions::BODY => $body,
        \GuzzleHttp\RequestOptions::DEBUG => true,
    ];

    try {
        $response = $client->post('https://api.sandbox.ebay.com/identity/v1/oauth2/token', $options);
        die(dump($response->getBody()->__toString(), $response));
    } catch (\Exception $e) {
        die(dump($e,$_GET, $authorization, $body, $options));
    }
}

// Start the authentication redirecting the user to the eBay's sign-in page
$get_request_token_url = 'https://signin.sandbox.ebay.com/authorize'
    . '?client_id=' . $appId
    . '&redirect_uri=' . $ruName
    . '&response_type=code'
    // Scope for User
    . '&scope=' . urlencode(
        'https://api.ebay.com/oauth/api_scope '.
        'https://api.ebay.com/oauth/api_scope/sell.account.readonly '.
        'https://api.ebay.com/oauth/api_scope/sell.account '
    );
header('Location: ' . $get_request_token_url);

由于文档含糊不清,我还尝试在查询字符串中直接设置 eBay 返回的 on-time/temporary code(所有其他参数应该在 body).我也尝试过将它们都发送到 body 并将它们附加到 query_string 但似乎没有任何效果......

我真的不知道还能尝试什么。

有人可以帮忙吗?

我用过 The League of Extraordinary Packages OAuth 2.0 Client 但为了与 Ebay 兼容做了一些修补:

Ebay 供应商class:

namespace Library\Ras\OAuth2\Client\Provider;

use League\OAuth2\Client\Provider\GenericProvider;

/**
 * Class Ebay
 * @package Library\Ras\OAuth2\Client\Provider
 */
class EbayProvider extends GenericProvider
{

    protected function getAccessTokenOptions(array $params)
    {
        $options = [
            'headers' => [
                'Accept' => 'application/json',
                'Content-Type' => 'application/x-www-form-urlencoded',
                'Authorization' => sprintf(
                    'Basic %s',
                    base64_encode(sprintf('%s:%s', $params['client_id'], $params['client_secret']))
                ),
            ],
        ];

        unset($params['client_id'], $params['client_secret']);

        if ($this->getAccessTokenMethod() === self::METHOD_POST) {
            $options['body'] = $this->getAccessTokenBody($params);
        }

        return $options;
    }
}

如果您使用的是 Guzzle < 6.0,则需要自定义请求工厂:

namespace Library\Ras\OAuth2\Tool;

use GuzzleHttp\Message\MessageFactory;
use GuzzleHttp\Message\Request;
use League\OAuth2\Client\Tool\RequestFactory as BaseRequestFactory;

/**
 * Class RequestFactory
 * @package Library\Ras\OAuth2\Tool
 */
class RequestFactory extends BaseRequestFactory
{

    /**
     * Creates a request using a simplified array of options.
     *
     * @param  null|string $method
     * @param  null|string $uri
     * @param  array $options
     *
     * @return Request
     */
    public function getRequestWithOptions($method, $uri, array $options = [])
    {
        $factory = new MessageFactory();
        return $factory->createRequest($method, $uri, $options);
    }
}

最后:

require __DIR__ . '/../vendor/autoload.php';

$client = new \Library\Ras\OAuth2\Client\Provider\EbayProvider([
    'clientId' => '<clientId>',
    'clientSecret' => '<clientSecret>',
    'redirectUri' => '<RUName>',
    'urlAuthorize' => 'https://signin.ebay.com/authorize',
    'urlAccessToken' => 'https://api.ebay.com/identity/v1/oauth2/token',
    'urlResourceOwnerDetails' => '',
    'scopeSeparator' => ' ',
    'scopes' => [
        'https =>//api.ebay.com/oauth/api_scope',
        'https =>//api.ebay.com/oauth/api_scope/buy.order.readonly',
        'https =>//api.ebay.com/oauth/api_scope/buy.order',
    ],
]);

// Only if your Guzzle version is < 6.0
$client->setRequestFactory(new \Library\Ras\OAuth2\Tool\RequestFactory());

if (array_key_exists('code', $_GET)) {
    $applicationToken = $_GET['code'];
    $accessToken = $client->getAccessToken('authorization_code', [
        'code' => $applicationToken,
    ]);
    echo 'User access token: ' . $accessToken;
} else {
    $url = $client->getAuthorizationUrl();
    header('Location: ' . $url);
}