我正在尝试连接到 LivePerson Engagement History API我遇到了一个我认为与正在生成的签名有关的问题。
首先,API 已经提供了必要的消费者 key 、消费者 secret 、访问 token 和 token secret 。所以我不必经历检索这些的过程。为了访问他们的 API,我只需要 provide the auth header .我已经使用 Postman 模拟了所有内容,并且一切正常。问题是当我尝试在类(class)中生成自己的时间戳/随机数/签名时。
这是我的类中发送 cURL 请求的方法:
private function execute($options = array())
{
if (!isset($options['url'])) {
return;
}
$ch = curl_init($options['url']);
$method = (isset($options['method'])) ? $options['method'] : 'GET';
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
if (isset($options['auth']) && $options['auth']) {
$timestamp = round(microtime(true) * 1000);
$nonce = $this->getNonce(11);
$version = "1.0";
$signatureMethod = "HMAC-SHA1";
$signature = $this->generateSignature($options, $timestamp, $nonce, $signatureMethod, $version);
$authHeader = "Authorization: OAuth oauth_consumer_key=\"{$this->consumerKey}\",oauth_token=\"{$this->accessToken}\",oauth_signature_method=\"{$signatureMethod}\",oauth_timestamp=\"{$timestamp}\",oauth_nonce=\"{$nonce}\",oauth_version=\"{$version}\",oauth_signature=\"{$signature}\"";
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
$authHeader,
"Content-Type: application/json"
));
}
if (isset($options['body']) && !empty($options['body'])) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($options['body']));
}
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
getNonce
我几乎直接从 https://github.com/BaglerIT/OAuthSimple/blob/master/src/OAuthSimple.php 复制的方法.这是我编写的生成签名的方法(已从各种 SO 帖子和其他来源拼凑而成):
protected function generateSignature($request, $timestamp, $nonce, $signatureMethod, $version)
{
$base = $request['method'] . "&" . rawurlencode($request['url']) . "&"
. rawurlencode("oauth_consumer_key=" . rawurlencode($this->consumerKey)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature_method=" . rawurlencode($signatureMethod)
. "&oauth_timestamp=" . $timestamp
. "&oauth_version=" . $version);
$key = rawurlencode($this->consumerSecret) . '&' . rawurlencode($this->tokenSecret);
$signature = base64_encode(hash_hmac('sha1', $base, $key, true));
return $signature;
}
我实际上可以将 Postman 的授权 header 复制并粘贴到我的
$authHeader
中。变量,并替换除时间戳/随机数/签名之外的所有内容,它可以工作。我现在从他们的服务器得到的响应是
[code] => 0005
但我在他们的文档中找不到关于响应代码的任何内容。编辑:我错过了查看响应 header - 确切的错误是无效签名。
最佳答案
我改变了两件事来让它工作。我错过了 oauth_token
在为签名创建基本字符串时 – 根据 OAuth Core 1.0 documentation , “参数按名称排序,使用字典字节值排序。”
所以我最终将参数重新排序为按字母顺序排列。下面是生成基本字符串的代码最终的样子:
$base = $request['method'] . "&" . rawurlencode($request['url']) . "&"
. rawurlencode("oauth_consumer_key=" . rawurlencode($this->consumerKey)
. "&oauth_nonce=" . rawurlencode($nonce)
. "&oauth_signature_method=" . rawurlencode($signatureMethod)
. "&oauth_timestamp=" . rawurlencode($timestamp)
. "&oauth_token=" . rawurlencode($this->accessToken)
. "&oauth_version=" . rawurlencode($version));
我还重新排序了 auth header 中的参数以匹配基本字符串的顺序:
$authHeader = "Authorization: OAuth oauth_consumer_key=\"{$this->consumerKey}\",oauth_nonce=\"{$nonce}\",oauth_signature_method=\"{$signatureMethod}\",oauth_timestamp=\"{$timestamp}\",oauth_token=\"{$this->accessToken}\",oauth_version=\"{$version}\",oauth_signature=\"{$signature}\"";
关于php - 在 PHP 中生成 OAuth 1 签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52785040/