簡體   English   中英

Google OAuth 簽名無效響應 (PHP)

[英]Google OAuth Signature Invalid response (PHP)

眼睛越來越痛,試圖找出導致這種情況的問題。 我正在縮小范圍,但我厭倦了更改不同的參數以使簽名通過。 我一直在將我的基本字符串和授權標頭與 google-code-playground 的 output 進行比較。

我一直在參考這篇文章,並認為我已經接近了:

PHP Oauth 簽名_無效

我的基本字符串:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM