3

这让我大吃一惊。我正在网站上实施朋友邀请计划,需要访问用户的雅虎联系人列表。为此,我使用 OAuth 和 yahoo REST api。以下是事件序列的完整概要:

我在developers.yahoo.com 上设置了一个项目,该项目配置为对联系人具有读取权限。它位于一个虚构的域上,我在我的主机文件中指向 127.0.0.1(很有可能是 localhost 导致了我的麻烦)。出于这个原因,虽然我的理解是,这只是意味着我有更少的限制,而不是更多的限制,但没有验证域。

首先,在服务器上我得到一个请求令牌:

https://api.login.yahoo.com/oauth/v2/get_request_token
    ?oauth_callback=http%3A%2F%2Fdev.mysite.com%2Fcallback.aspx
    &oauth_consumer_key=MYCONSUMERKEY--
    &oauth_nonce=xmaf8ol87uxwkxij
    &oauth_signature=WyWWIsjN1ANeiRpZxa73XBqZ2tQ%3D
    &oauth_signature_method=HMAC-SHA1
    &oauth_timestamp=1328796736
    &oauth_version=1.0

返回(格式化以模糊尝试清晰):

oauth_token=hxcsqgj
&oauth_token_secret=18d01302348049830942830942630be6bee5
&oauth_expires_in=3600
&xoauth_request_auth_url
    =https%3A%2F%2Fapi.login.yahoo.com%2Foauth%2Fv2%2Frequest_auth
     %3Foauth_token%3Dhxcsqgj
&oauth_callback_confirmed=true"

然后我向用户弹出 xoauth_request_auth_url 页面,并在我的回调页面中接收验证码。然后我将其发送回我的服务器,以便我可以将其交换为访问令牌:

https://api.login.yahoo.com/oauth/v2/get_token
    ?oauth_consumer_key=MYCONSUMERKEY--
    &oauth_nonce=yxhd1nymwd03x189
    &oauth_signature=c%2F6GTcybGJSQi4TOpvueLUO%2Fgrs%3D
    &oauth_signature_method=HMAC-SHA1
    &oauth_timestamp=1328796878
    &oauth_token=hxcqgjs
    &oauth_verifier=b8ngvp        <- verifier given via callback
    &oauth_version=1.0

这似乎有效,我得到了一个访问令牌:

oauth_token=MYVERYLONGACCESSTOKEN--
&oauth_token_secret=MYOATHTOKENSECRET
&oauth_expires_in=3600
&oauth_session_handle=ADuXM093mTB4bgJPKby2lWeKvzrabvCrmjuAfrmA6mh5lEZUIin6
&oauth_authorization_expires_in=818686769
&xoauth_yahoo_guid=MYYAHOOGUID

然后我立即尝试使用访问令牌和 GUID 获取联系人列表:

http://social.yahooapis.com/v1/user/MYYAHOOGUID/contacts

(HTTP Header added and formatted with line breaks for clarity...)

Authorization: OAuth
    realm="yahooapis.com",
    oauth_consumer_key="MYCONSUMERKEY--",
    oauth_nonce="nzffzj5v82mgf4mx",
    oauth_signature="moVJywesuGaPN5YHYKqra4T2ips%3D",
    oauth_signature_method="HMAC-SHA1",
    oauth_timestamp="1328796907",
    oauth_token="MYVERYLONGACCESSTOKEN--",
    oauth_version="1.0"

从这个电话我得到一个 401 Unauthorized,但似乎不可能找出原因。为了签署这些电话,我在 github 上使用了这个 oath lib。我不认为它在做任何非凡或不兼容的事情。对于签名,我包括消费者密钥/秘密和访问令牌/秘密。我查看了正在散列的签名库,它看起来与雅虎文档中可见的示例形式相同。我猜我在参数中遗漏了一些没有被散列的东西。有没有办法找出为什么调用是未经授权的,或者有没有人知道一个例子,说明签名库和授权标头必须采用什么形式?

4

2 回答 2

3

自己解决了这个问题。添加答案以防万一它碰巧帮助任何犯我犯同样愚蠢错误的人。当我进行 API 调用时,我使用的是从原始请求令牌调用返回的令牌密码,而不是从访问令牌调用返回的新密码。

哎呀。

于 2012-02-09T20:03:13.520 回答
0

这是我解决的代码,如果 yahooapis 返回 403 禁止使用的受信任代码:

参考: https ://developer.yahoo.com/yql/guide/yql-code-examples.html#yql_php https://github.com/danzisi/YQLQueryYahooapis

    init CODE

/**
 * Call the Yahoo Contact API
 *
 * https://developer.yahoo.com/yql/guide/yql-code-examples.html#yql_php
 *
 * @param string $consumer_key obtained when you registered your app
 * @param string $consumer_secret obtained when you registered your app
 * @param string $guid obtained from getacctok
 * @param string $access_token obtained from getacctok
 * @param string $access_token_secret obtained from getacctok
 * @param bool $usePost use HTTP POST instead of GET
 * @param bool $passOAuthInHeader pass the OAuth credentials in HTTP header
 * @return response string with token or empty array on error
 */ 
function call_yql($consumer_key, $consumer_secret, $querynum, $access_token, $access_token_secret, $oauth_session_handle, $usePost=false, $passOAuthInHeader = true){
  global $godebug;
  $response = array();

  if ($consumer_key=='' || $consumer_secret=='' || $querynum=='' || $access_token=='' || $access_token_secret=='' || $oauth_session_handle) return array('0' => 'Forbidden');

  if ($querynum == 1) {
    $url = 'https://query.yahooapis.com/v1/yql';
    // Show my profile
    $params['q'] = 'select * from social.profile where guid=me';
  } elseif ($querynum == 2) {
    $url = 'https://query.yahooapis.com/v1/yql';
    // here other query

  } 

  $params['format'] = 'json';  //json xml
  $params['Authorization'] = 'OAuth';  
  $params['oauth_session_handle'] =  $oauth_session_handle;
  $params['realm'] = 'yahooapis.com';
  $params['callback'] = 'cbfunc';
  $params['oauth_version'] = '1.0';
  $params['oauth_nonce'] = mt_rand();
  $params['oauth_timestamp'] = time();
  $params['oauth_consumer_key'] = $consumer_key;
  $params['oauth_callback'] = 'oob';
  $params['oauth_token'] = $access_token;

  $params['oauth_signature_method'] = 'HMAC-SHA1';
  $params['oauth_signature'] = oauth_compute_hmac_sig($usePost? 'POST' : 'GET', $url, $params, $consumer_secret, $access_token_secret);

  if ($passOAuthInHeader) {
    $query_parameter_string = oauth_http_build_query($params, true);
    $header = build_oauth_header($params, "yahooapis.com");
    $headers[] = $header;
  } else {
    $query_parameter_string = oauth_http_build_query($params);
  }

  // POST or GET the request
  if ($usePost) {
    $request_url = $url;   
    logit("call_yql:INFO:request_url:$request_url");
    logit("call_yql:INFO:post_body:$query_parameter_string");
    $headers[] = 'Content-Type: application/x-www-form-urlencoded';
    $response = do_post($request_url, $query_parameter_string, 443, $headers);
  } else {
    $request_url = $url . ($query_parameter_string ? ('?' . $query_parameter_string) : '' );
    logit("call_yql:INFO:request_url:$request_url");
    $response = do_get($request_url, 443, $headers);
  }

  // extract successful response
  if (! empty($response)) {   
    list($info, $header, $body) = $response;  

    if ($godebug==true) {
        echo "<p>Debug: function call_yql info: <pre>" . print_r($info, TRUE) . "</pre></p>";
        echo "<p>Debug: function call_yql header: <pre>" . print_r($header, TRUE) . "</pre></p>";
        echo "<p>Debug: function call_yql body: <pre>" . print_r($body, TRUE) . "</pre></p>";
    }
    if ($body) {
      $body = GetBetween($body, 'cbfunc(', ')');   
      $full_array_body = json_decode($body);
      logit("call_yql:INFO:response:");  
      if ($godebug==true) echo "<p>Debug: function call_yql full_array_body: <pre>" . print_r($full_array_body, TRUE) . "</pre></p>";
      } 

  }
  // return object 
  return $full_array_body->query;
}
    END code
于 2014-04-26T13:44:36.127 回答