【问题标题】:Oauth HMAC-SHA1 authentication to get contacts from Yahoo! Contacts API [duplicate]从 Yahoo! 获取联系人的 Oauth HMAC-SHA1 身份验证联系人 API [重复]
【发布时间】:2013-01-11 21:57:44
【问题描述】:

可能重复:
Get contacts using Yahoo Contacts API

我正在开发一个系统来从用户那里获取 Yahoo 联系人。我已经完成了http://developer.yahoo.com/oauth/guide/oauth-auth-flow.html 的所有步骤,并且我已经获得了访问令牌和令牌密码。

我在使用 HMAC-SHA1 算法签名时遇到问题,我已按照 http://developer.yahoo.com/oauth/guide/oauth-signing.html 中的步骤生成签名密钥,但是当我向给定用户请求联系人时,我收到错误:

<yahoo:error xmlns:yahoo='http://yahooapis.com/v1/base.rng'
    xml:lang='en-US'>
    <yahoo:description>Please provide valid credentials. OAuth oauth_problem="signature_invalid", realm="yahooapis.com"</yahoo:description>
</yahoo:error>

这是我负责生成签名密钥的代码:

$s =  'oauth_consumer_key='.rawurlencode($yahoo_consumer_key).'&';
$s .= 'oauth_nonce='.rawurlencode(uniqid()).'&';
$s .= 'oauth_signature_method='.rawurlencode('HMAC-SHA1').'&';
$s .= 'oauth_timestamp='.rawurlencode(time()).'&';
$s .= 'oauth_token='.rawurlencode($ouathToken).'&';
$s .= 'oauth_version='.rawurlencode('1.0').'&';
$s .= 'realm='.rawurlencode('yahooapis.com');

$baseString ='GET&'.rawurlencode('http://social.yahooapis.com/v1/user/'.$guid.'/contacts').'&'.rawurlencode($s);

$signingKey = rawurlencode($yahoo_consumer_secret).'&'.rawurlencode($ouathTokenSecret);

$signature = urlencode(base64_encode(hash_hmac('sha1', $baseString, $signingKey, true)));

curl_setopt_array($ch, array(
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => TRUE,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_HTTPGET => true,
            CURLOPT_POST       => false,
            CURLOPT_URL => 'http://social.yahooapis.com/v1/user/'.$guid.'/contacts'.    
                                  '?realm=yahooapis.com'.
                                  '&oauth_consumer_key='.$yahoo_consumer_key.
                                  '&oauth_nonce='.uniqid().
                                  '&oauth_signature_method=HMAC-SHA1'.
                                  '&oauth_timestamp='.time().
                                  '&oauth_token='.$ouathToken.
                                  '&oauth_version=1.0'.
                                  '&oauth_signature='.$signature
        ));

$result = curl_exec($ch);

谁能帮我告诉我错误在哪里?我没有正确生成签名密钥吗?

谢谢。

【问题讨论】:

    标签: php oauth yahoo-api


    【解决方案1】:

    看起来您在某些地方使用 urlencode 而不是 rawurlencode,整个过程中将使用“+”而不是“%20”之类的东西作为空格。雅虎文档(对这个领域来说不是很好)显示了使用 rawurlencode 而不是 urlencode 的“规范化”标题/URL 字符串。除了您对请求进行编码的方式之外,它看起来不错。

    *已编辑:我混淆了 rawurlencode 和 urlencode。 Rawurlencode 使用 OAuth 要求的 RFC 3986:http://oauth.net/core/1.0/#encoding_parameters

    你也是双重编码$s!不要这样做 - 创建 $s 时根本不要使用 rawurlencode,而是在构建 $baseString 或 URL 时对其进行编码 在创建 $s 时在顶部对其进行编码,然后不要在 $ 中再次对其进行编码基本字符串。

    【讨论】:

    • 在这一行: $baseString ='GET&'.rawurlencode('social.yahooapis.com/v1/user/'.$guid.'/…; 我必须用 urlencode 替换 rawurlencode?我已经尝试了很多方法,但我仍然得到同样的错误.. 你可以更具体?
    • 对不起,我完全倒退了 - 一切都应该是 rawurlencoded,它使用 RFC 3986。我把它们弄混了。但是,根据 OAuth 文档,根据 RFC3986,只能对保留字符进行编码,而其他所有内容都不必编码。查看oauth.net/core/1.0 以确保您的每一步都正确。我已经使用正确的 PHP 函数编辑了我的答案 - 确保您没有混合/匹配原始/urlencoding,并且使用 rawurlencode() 一切都是统一的;
    • 另外,检查您的输出以确保没有任何不属于 RFC 3986 保留字符列表的编码字符:PHP 有时会根据您的版本使用 raw/urlencoding 做一些奇怪的事情:faqs.org/rfcs/rfc3986.html
    • 刚刚再次编辑以包含有关双重编码 $s 的部分 - 这会导致问题。确保所有内容都使用 RFC3986 进行编码,并且您没有对 ALPHA、DIGIT、'-'、'.'、'_'、'~' 进行编码,并且还确保你没有对任何内容进行双重编码。这样就解决了。
    猜你喜欢
    • 2013-12-27
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多