Почему я получаю HTTP 401 Несанкционированный от моего вызова API контактов Yahoo? - PullRequest
3 голосов
/ 09 февраля 2012

Это сводит меня с ума. Я внедряю схему приглашения друзей на веб-сайт, и мне нужен доступ к списку контактов пользователя Yahoo. Для этого я использую OAuth и API REST Yahoo. Вот полное изложение последовательности событий:

У меня есть проект, настроенный на developers.yahoo.com, для которого настроен доступ на чтение контактов. Он находится в готовом домене, который я указываю на 127.0.0.1 в моем файле hosts (на случай, если 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 Несанкционированный, но кажется невозможным выяснить, почему. Чтобы подписать эти вызовы, я использую эту библиотеку присяги на github . Я не думаю, что это делает что-то необычное или несовместимое. Для подписи я включаю потребительский ключ / секрет и токен доступа / секрет. Я посмотрел на базу сигнатур, которая хэшируется, и она выглядит так же, как примеры, видимые в документации Yahoo. Я предполагаю, что я что-то упускаю из параметров, которые не хэшируются. Есть ли способ узнать, почему вызов является неавторизованным, или кто-нибудь знает пример, показывающий, какую именно форму должны принимать база подписи и заголовок авторизации?

Ответы [ 2 ]

3 голосов
/ 10 февраля 2012

Решил это сам.Добавление ответа на всякий случай поможет любому, кто совершит ту же глупую ошибку, что и я.Когда я делал вызов API, я использовал секретный токен, возвращенный из исходного запроса токена, вместо нового, возвращенного из вызова токена доступа.

Упс.

0 голосов
/ 26 апреля 2014

это код, который я решил, доверенный код для использования, если yahooapis возвращает 403 запрещенных:

Ссылка: https://developer.yahoo.com/yql/guide/yql-code-examples.html#yql_php https://github.com/danzisi/YQLQueryYahooapis

<code>    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) . "
"; echo "

Отладка: заголовок функции call_yql:

" . print_r($header, TRUE) . "
"; echo "

Отладка: тело функции call_yql:

" . print_r($body, TRUE) . "
";} if ($ body) {$ body = GetBetween($ body, 'cbfunc (', ')'); $ full_array_body = json_decode ($ body); logit ("call_yql: INFO: response:"); if ($ godebug == true) echo "

Debug:function call_yql full_array_body:

" . print_r($full_array_body, TRUE) . "
";}} // вернуть объект return $ full_array_body-> query;} END код
...