[英]Google OAuth Signature Invalid response (PHP)
眼睛越来越痛,试图找出导致这种情况的问题。 我正在缩小范围,但我厌倦了更改不同的参数以使签名通过。 我一直在将我的基本字符串和授权标头与 google-code-playground 的 output 进行比较。
我一直在参考这篇文章,并认为我已经接近了:
我的基本字符串:
GET&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetRequestToken&oauth_callback%3Dhttp%253A%252F%252Fgooglecodesamples.com%252Foauth_playground%252Findex.php%26oauth_consumer_key%3Danonymous%26oauth_nonce%3D1f8a27974826a0001f679186898bb79a%26oauth_signature_method%3DHMAC- SHA1%26oauth_timestamp%3D1313023952% 26oauth_version%3D1.0%26scope%3Dhttps%253A%252F%252Fwww.google.com%252Fcalendar%252Ffeeds%252F
授权标头:
OAuth oauth_consumer_key="anonymous", oauth_nonce="1f8a27974826a0001f679186898bb79a", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1313023952", oauth_callback="http%3A%2F%2Fgooglecodesamples.com%2Foauth_playground%2Findex.php", oauth_version=" 1.0", oauth_signature="nHL5107wlVXrB5GJjyDClpc5pJs%3D"0signature_invalid
主要 Function:
private function oAuthGetRequestToken()
{
echo "<pre>";
$secret = 'anonymous';
$url = 'https://www.google.com/accounts/OAuthGetRequestToken';
$scope = 'https://www.google.com/calendar/feeds/';
$authParams = array(
'oauth_consumer_key' => 'anonymous',
'oauth_nonce' => self::generateNonce(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => time(),
'oauth_callback' => 'http://googlecodesamples.com/oauth_playground/index.php',
'oauth_version' => '1.0');
$unsignedBaseString = self::getBaseString('GET', $url, $authParams, $scope);
$unsignedKey = array($authParams['oauth_consumer_key'], $secret);
$unsignedKeyParts = array_map('urlencode', $unsignedKey);
$key = implode('&', $unsignedKeyParts);
$oauth_signature = self::hmacsha1($key, $unsignedBaseString);
$authParams['oauth_signature'] = $oauth_signature;
$rest = new Rest();
$oAuthGetRequestTokenResponse = $rest->OAuthHttpGetRequest($url, $authParams, $scope);
print_r($oAuthGetRequestTokenResponse);
}
辅助功能:
protected function generateNonce()
{
$nonce = hash('md5', self::makeRandomString());
return $nonce;
}
protected function makeRandomString($bits = 256)
{
$bytes = ceil($bits / 8);
$return = '';
for ($i = 0; $i < $bytes; $i++) {
$return .= chr(mt_rand(0, 255));
}
return $return;
}
protected function hmacsha1($key, $data)
{
return base64_encode(hash_hmac('sha1', $data, $key, true));
}
protected function getBaseString($method, $url, $authParams, $scope)
{
$authString = '';
foreach($authParams as $key => $value)
$authString .= $key . "=" . urlencode($value) . "&";
$authString = rtrim($authString, '&');
$baseString = $method . '&' . urlencode($scope) . '&' . $authString;
return $baseString;
}
休息/请求 function:
public function OAuthHttpGetRequest($url, $authParams, $scope)
{
$oAuthHeaders = '';
$oAuthHttpGetResponse;
foreach($authParams as $key=>$value)
{
$oAuthHeaders .= $key . '="' . urlencode($value) . '", ';
}
$oAuthHeaders = rtrim($oAuthHeaders, ', ');
$authString = "OAuth " . $oAuthHeaders;
echo "<br/>" . $authString;
$urlWithScope = $url . '?scope=' . urlencode($scope);
if($curlHandle = curl_init())
{
curl_setopt($curlHandle, CURLOPT_URL, $urlWithScope);
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array("Authorization: " . $authString));
//curl_setopt($curlHandle, CURLOPT_POST, TRUE);
//curl_setopt($curlHandle, CURLOPT_POSTFIELDS, );
curl_setopt($curlHandle, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curlHandle, CURLOPT_SSL_VERIFYHOST, 0);
$oAuthHttpGetResponse = curl_exec($curlHandle);
echo curl_errno($curlHandle);
echo curl_error($curlHandle);
curl_close($curlHandle);
}
else
die("Could not instance cURL, is the module enabled?");
return $oAuthHttpGetResponse;
}
在第一次阅读时,我认为您的问题出在 getBaseString function 中:
$baseString = $method . '&' . urlencode($scope) . '&' . $authString;
我认为您应该在这里使用 REQUEST TOKEN ENDPOINT 而不是 scope ...
使用附加参数请求范围,因为通常 OAuth 协议不指定范围的存在 - 它们是更好地调整 API 访问所需的扩展,但它们不是协议工作的强制性。
在创建基本签名字符串时,包含在 $method 之后的 URL 始终是将接收请求的 URL...
在你的情况下,我认为应该是:
$baseString = $method . '&' . urlencode($url) . '&' . $authString;
- - 添加在 - -
更清楚一点:第一次请求 REQUEST 令牌时,基本字符串应包含 REQUET TOKEN 端点的 URL...
稍后请求 ACCESS 令牌时,基本字符串应包含 ACCESS TOKEN 端点的 URL
最后,在获得 ACCESS 令牌后,您正在访问资源(范围),那么基本字符串应包含资源的 URL(在您的示例中也称为 scope)...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.