我正在尝试连接到LivePerson Engagement History API,但遇到了一个与生成的签名有关的问题。
首先,API已经提供了必需的使用者密钥,使用者密钥,访问令牌和令牌密钥。因此,我不必经历检索这些过程的过程。为了访问他们的API,我只需要provide the auth header。我已经使用Postman模拟了所有内容,并且一切正常。问题是当我尝试在班级中生成自己的时间戳记/即刻/签名时。
这是我的类中发送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;
}
我直接从https://github.com/BaglerIT/OAuthSimple/blob/master/src/OAuthSimple.php复制了getNonce
方法。
这是我编写的用于生成签名的方法(该签名已从各种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复制并粘贴到我的$authHeader
变量中,并替换除时间戳记/随机数/签名以外的所有内容,并且可以正常工作。
我现在从他们的服务器收到的响应是[code] => 0005
,但是我在他们的文档中找不到任何有关响应代码的信息。
编辑:我错过了查看响应标头-确切的错误是无效签名。
答案 0 :(得分:1)
为了使此功能生效,我做了两件事。在创建签名的基本字符串时,我缺少了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标头中的参数进行了重新排序,以匹配基本字符串的顺序:
$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}\"";
答案 1 :(得分:1)
$base = $request['method']
. '&' . rawurlencode($request['url'])
. '&' . rawurlencode('oauth_consumer_key=' . $this->consumerKey)
. rawurlencode('&oauth_nonce=' . $nonce)
. rawurlencode('&oauth_signature_method=' . $signatureMethod)
. rawurlencode('&oauth_timestamp=' . $timestamp)
. rawurlencode('&oauth_version=' . $version)
. rawurlencode('&' . http_build_query($data));
$key = rawurlencode($this->consumerSecret) . '&';
$signature = rawurlencode(base64_encode(hash_hmac('SHA1', $base, $key, true)));
如果您要进行POST,请确保包括您发布的数据,否则签名将无效。
CURLOPT_HTTPHEADER => array(
"authorization: OAuth oauth_consumer_key=\"{$consumerKey}\",oauth_signature_method=\"{$signatureMethod}\",oauth_timestamp=\"{$timestamp}\",oauth_nonce=\"{$nonce}\",oauth_version=\"{$version}\",oauth_signature=\"{$oauthSignature}\"",
"content-type: application/x-www-form-urlencoded",
),
标题应该和上面一样
答案 2 :(得分:0)
这个固定版本对我有用:
function generateOauthSignature($method, $url, $consumerKey, $nonce, $signatureMethod, $timestamp, $version, $consumerSecret, $tokenSecret, $tokenValue, $extraParams = array())
{
$base = strtoupper($method) . "&" . rawurlencode($url) . "&"
. rawurlencode("oauth_consumer_key=" . $consumerKey
. "&oauth_nonce=" . $nonce
. "&oauth_signature_method=" . $signatureMethod
. "&oauth_timestamp=" . $timestamp
. "&oauth_token=" . $tokenValue
. "&oauth_version=" . $version);
if (!empty($extraParams)) {
$base .= rawurlencode("&" . http_build_query($extraParams));
}
$key = rawurlencode($consumerSecret) . '&' . rawurlencode($tokenSecret);
$signature = base64_encode(hash_hmac('sha1', $base, $key, true));
return rawurlencode($signature);
}
以下 twitter 线程帮助了我:https://twittercommunity.com/t/how-to-generate-oauth-signature-when-post-json-body-in-php/87581