HERE REST API OAuth 2.0 令牌请求(带有 1.0 header)错误

HERE REST API OAuth 2.0 Token Request (with a 1.0 header) Error

我一直在努力让我的 PHP 应用程序创建一个成功的令牌请求,因为根据文档 here

最终设法让它与 Postman 一起工作

显然 API 正在使用 OAuth 2.0,这就是为什么我希望发送 grant_typeclient_idclient_secretexpires_in(如果我不要指定这些字段之一,然后 API 会成功地告诉我它丢失了)。

现在我遇到的问题是我必须生成的这个 OAuth 1.0 授权 Header,邮递员似乎没有问题这样做,但是试图在 PHP 中做到这一点我刚收到 API 返回的关于签名不匹配的错误:

array:6 [
  "errorId" => "ERROR-fde4f0f1-9d5c-43fd-80eb-056cbf2c3259"
  "httpStatus" => 401
  "errorCode" => 401300
  "message" => "Signature mismatch. Authorization signature or client credential is wrong."
  "error" => "invalid_client"
  "error_description" => "errorCode: '401300'. Signature mismatch. Authorization signature or client credential is wrong."
]

我尝试了各种调试,其中很多都给我不同的错误,然后我一直回到这个错误,所以签名一定是问题所在。

我创建了以下 class here 来处理生成 header,从 guzzle/oauth-subscriber 包中的 class 获得了一些指导。

这是正在生成的请求 header 的示例:

array:2 [
  "Content-Type" => "application/x-www-form-urlencoded"
  "Authorization" => "OAuth oauth_consumer_key="XXXXXXXXXXXX",oauth_signature_method="HMAC-SHA256",oauth_timestamp="1583629976",oauth_nonce="Br2HsCVzsaEe3KswBhtCzsSxjUDWgX56",oauth_version="1.0",oauth_signature="G7%2B5f2v2Kdx3rp%2B28DcuJRBvhi9H7fHC1mFLqJIgmMc%3D""
]

请求body:

array:4 [
  "grant_type" => "client_credentials"
  "client_id" => "XXXXXXXXXXXX"
  "client_secret" => "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  "expires_in" => 87000
]

已替换敏感信息,但 consumer_key 是正确的,与 client_id 的值相同,consumer_secretclient_secret

的值相同

无论我如何尝试更改 signUsingHmac() 方法来更改签名,它都不起作用,对我来说一切正常 D:

有人有什么想法吗?

如果我能让它很好地工作,我会把它拉出到包中,使 PHP 中的 API 的身份验证不那么痛苦。

编辑:

我尝试完全按照文档 here 中显示的方式形成签名,但不幸的是它仍然没有用,这就是我的 $baseString 在传递到哈希方法时的样子:

POST&https%3A%2F%2Faccount.api.here.com%2Foauth2%2Ftoken&grant_type%3Dclient_credentials%26oauth_consumer_key%3DXXbXbXbXbXbXbXb%26oauth_nonce%3DrZNNSZGOOIHFFtLboCjdAheCmKJmOYSp%26oauth_signature_method%3DHMAC-SHA256%26oauth_timestamp%3D1583640503%26oauth_version%3D1.0

我还创建了一个新的要点 here 我的更新创建了这个 $baseString

干杯, 马特

似乎 access_id 和 access_key 都在请求 body 中传递,"grant_type" => "client_credentials" 只需要在 body 中,而access_id and access_key 应在 header 中传递。你可以先在邮递员里试试,如果成功了,请回复

我创建了一个有效的要点。 一些建议:

  • 所有值都需要 urlenconde()
  • 您需要使用的字符串 对于签名,请求需要包括:方法(大写)& URL (urlecode) & 参数列表 (url 编码)
  • 签名密钥是您的消费者密钥(url编码)后跟 &。这是因为通常您的签名密钥需要我的消费者秘密和秘密令牌。在这种情况下,我们没有秘密令牌

对于签名基本字符串的参数列表,您需要包括所有 oauth_ 参数和您的 grant_type,因为您还需要包括 body 参数。这些key的排序很关键

部分代码PHP代码:

$keyId = getenv('HERE_API_KEY_ID');
$keySecret = getenv('HERE_API_KEY_SECRET');

$httpBody = [
    "grant_type" => "client_credentials"
];
$httpMethod = "POST";
$httpUrl = 'https://account.api.here.com/oauth2/token';


$oauthNonce = mt_rand();
$oauthTimestamp = time();
$oauthSignatureMethod= "HMAC-SHA256";
$oauthVersion = "1.0";


$baseString = $httpMethod."&". urlencode($httpUrl);

$oauth1Param = [
    'oauth_consumer_key' => $keyId,
    'oauth_signature_method' => $oauthSignatureMethod,
    'oauth_timestamp' => $oauthTimestamp,
    'oauth_nonce' => $oauthNonce,
    'oauth_version' => $oauthVersion
];


$paramString =

        "grant_type=client_credentials&".
        "oauth_consumer_key=". urlencode($oauth1Param['oauth_consumer_key']).
        "&oauth_nonce=". urlencode($oauth1Param['oauth_nonce']).
        "&oauth_signature_method=". urlencode($oauth1Param['oauth_signature_method']).
        "&oauth_timestamp=". urlencode($oauth1Param['oauth_timestamp']).
//        "&oauth_token=".
        "&oauth_version=". urlencode($oauth1Param['oauth_version'])
;

echo $paramString.PHP_EOL;
$baseString = $baseString . "&" . urlencode($paramString);
echo $baseString . PHP_EOL;
$signingKey= urlencode($keySecret) . "&";
$signature = urlencode(
    base64_encode(
    hash_hmac(
        'sha256',
        $baseString,
        $signingKey,
        true
    )
    )
);

$oauth1Param['oauth_signature']  =  $signature;
echo "RUNTIME SIGNATURE : " . $signature .PHP_EOL;

我创建了一个有效的 GIST,您唯一需要更改的是 $keyId 和 $keySecret。 https://gist.github.com/roberto-butti/736c38c796ede70c719f6a21a752c971

这份文档非常有用:https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a/creating-a-signature