Curl 雅虎API和可怕的oauth问题;签名“无效”;

Curl 雅虎API和可怕的oauth问题;签名“无效”;,curl,oauth,yahoo,hmacsha1,Curl,Oauth,Yahoo,Hmacsha1,我在这里读过很多其他的帖子,但似乎找不到一个能给出令人信服的答案 我一直在关注这些文档,现在我有了一套很好的凭证和登录用户的用户id。到目前为止,我一直在使用https和明文签名方法 现在我希望收到一些关于用户的信息,并且必须使用HMACS-SHA1方法对我的请求进行签名 基本上,像这里的许多其他人一样,我得到了请提供有效凭证的许可。OAuth OAuth_problem=“签名无效”,realm=“yahooapi.com”错误消息 这是我的代码: function getYahooUser(

我在这里读过很多其他的帖子,但似乎找不到一个能给出令人信服的答案

我一直在关注这些文档,现在我有了一套很好的凭证和登录用户的用户id。到目前为止,我一直在使用https和明文签名方法

现在我希望收到一些关于用户的信息,并且必须使用HMACS-SHA1方法对我的请求进行签名

基本上,像这里的许多其他人一样,我得到了请提供有效凭证的许可。OAuth OAuth_problem=“签名无效”,realm=“yahooapi.com”错误消息

这是我的代码:

function getYahooUser($userID, $oauthToken, $oauthSecret)
{
   // $url = 'https://social.yahooapis.com/v1/user/' . $userID .'/profile?';
    $ch = curl_init();

    $s =  'oauth_consumer_key='.config::yahooConsumerKey.'&';
    $s .= 'oauth_nonce='.generateRandomString().'&';
    $s .= 'oauth_signature_method=HMAC-SHA1&';
    $s .= 'oauth_timestamp='.time().'&';
    $s .= 'oauth_token='.$oauthToken.'&';
    $s .= 'oauth_version=1.0&';
    $s .= 'realm=yahooapis.com';

    $baseString ='GET&'.rawurlencode('https://social.yahooapis.com/v1/user/'.$userID.'/profile').'&'.rawurlencode($s);
    $signingKey = rawurlencode(config::yahooConsumerSecret).'&'.rawurlencode($oauthSecret);
    $signature = rawurlencode(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 => 'https://social.yahooapis.com/v1/user/'.$userID.'/profile'.
            '?realm=yahooapis.com'.
            '&oauth_consumer_key='.config::yahooConsumerKey.
            '&oauth_nonce='.generateRandomString().
            '&oauth_signature_method=HMAC-SHA1'.
            '&oauth_timestamp='.time().
            '&oauth_token='.$oauthToken.
            '&oauth_version=1.0'.
            '&oauth_signature='.$signature
    ));

$output = curl_exec($ch);
    var_dump($output);

    return $output;

}

有人知道我做错了什么吗?

说真的,雅虎api令人震惊

Ok使用Joe Chung的oauth示例解决了这个问题,这些示例可从yahoo开发者网络获得

诀窍是在将从gettoken请求获得的身份验证令牌添加到签名创建中之前,对其进行url解码

这是我完整的yahoo函数,如果您有相同的问题,那么只需在我的config::params中包含您的变量

主要功能:

function doYahoo() //returns a url for the user to click to start auth
{

    require('Yahoo/YahooCurl.php');
    new YahooCurl;
    $yahooReply = getYahooRequestToken();
    $yahooReplyToArray = explode("&", $yahooReply);
    $yahooOauthToken = $yahooReplyToArray[0];
    $yahooOauthToken = substr($yahooOauthToken, 12);

    $yahooOauthTokenSecret = $yahooReplyToArray[1];
    $yahooOauthTokenSecret = substr($yahooOauthTokenSecret,19);


    $expire = time() + 60 * 60 * 24 * 7;
    setcookie("yahooSecret", $yahooOauthTokenSecret, $expire, "/", null);

    $YahooURL = 'https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token=' . $yahooOauthToken;
    return $YahooURL;

}

if(isset($_GET['yahoo']))
{

    $yahoooAuthToken = $_GET['oauth_token'];
    $yahoooAuthVerifier = $_GET['oauth_verifier'];

    require('Yahoo/YahooCurl.php');
    new YahooCurl;

    $yahooReply = getYahooAccessToken($yahoooAuthVerifier, $yahoooAuthToken, $_COOKIE['yahooSecret']);
    $yahooReplyToArray = explode("&", $yahooReply);
    $yahoooAuthToken = $yahooReplyToArray[0];
    $yahoooAuthToken = substr($yahoooAuthToken,12);
    $yahoooAuthToken = urldecode($yahoooAuthToken);
    $yahoooAuthTokenSecret = $yahooReplyToArray[1];
    $yahoooAuthTokenSecret = substr($yahoooAuthTokenSecret,19);
    $YahooUserID = $yahooReplyToArray[5];
    $YahooUserID = substr($YahooUserID,18);
    $YahooRefreshToken = $yahooReplyToArray[3];
    $YahooRefreshToken = substr($YahooRefreshToken,21);

    $expire = time() + 60 * 60 * 24 * 7;
    setcookie("yahooRefresh", $YahooRefreshToken, $expire, "/", null);

    $yahooUserData = getYahooUser($YahooUserID,$yahoooAuthToken,$yahoooAuthTokenSecret);

    //do what you want with $yahooUserData
}
和YahooCurl.php

class YahooCurl
{
    public $YahooRequestToken;
}

function getYahooRequestToken()
{

    $params = array(
        'oauth_nonce' => urlencode(generateRandomString()),
        'oauth_timestamp' => time(),
        'oauth_consumer_key' => config::yahooConsumerKey,
        'oauth_signature_method' => 'plaintext',
        'oauth_signature' => config::yahooConsumerSecret . '%26',
        'oauth_version' => '1.0',
        'oauth_callback' => config::yahooCallBackDomain);

    $url = 'https://api.login.yahoo.com/oauth/v2/get_request_token';
    $postData = '';


    foreach ($params as $k => $v) {
        $postData .= $k . '=' . $v . '&';
    }
    rtrim($postData, '&');

    //var_dump($postData);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_POST, count($postData));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
}

function generateRandomString($length = 6)
{
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}

function getYahooAccessToken($oauthVerifier, $oauthToken, $oauthSecret)
{

    $url = 'https://api.login.yahoo.com/oauth/v2/get_token?oauth_consumer_key=' .urlencode(config::yahooConsumerKey) .
        '&oauth_signature_method=' . urlencode('plaintext') .
        '&oauth_version=' . urlencode('1.0') .
        '&oauth_verifier=' . urlencode($oauthVerifier) .
        '&oauth_token=' . urlencode($oauthToken) .
        '&oauth_timestamp=' . urlencode(time()) .
        '&oauth_nonce=' .urlencode(generateRandomString()) .
        '&oauth_signature=' . config::yahooConsumerSecret . '%26' . $oauthSecret;

    $ch = curl_init();

    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
//  curl_setopt($ch,CURLOPT_HEADER, false);

    $output=curl_exec($ch);

    curl_close($ch);
    return $output;
}

function getYahooUser($userID, $oauthToken, $oauthSecret)
{

    $ch = curl_init();

    $url = 'https://social.yahooapis.com/v1/user/'. $userID . '/profile';
    $params['oauth_consumer_key'] = config::yahooConsumerKey;
    $params['oauth_nonce'] = generateRandomString();
    $params['oauth_signature_method'] = 'HMAC-SHA1';
    $params['oauth_timestamp'] = time();
    $params['oauth_token'] = $oauthToken;
    $params['oauth_version'] = '1.0';
    $params['oauth_signature'] =
        oauth_compute_hmac_sig('GET', $url, $params,
            config::yahooConsumerSecret, $oauthSecret);

    $query_parameter_string = oauth_http_build_query($params);
    $request_url = $url . ($query_parameter_string ?
            ('?' . $query_parameter_string) : '' );


    curl_setopt($ch, CURLOPT_URL, $request_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    $output = curl_exec($ch);
    var_dump($output);

    return $output;

}

    function oauth_compute_hmac_sig($http_method, $url, $params, $consumer_secret, $token_secret)
    {

        $base_string = signature_base_string($http_method, $url, $params);
        $signature_key = rfc3986_encode($consumer_secret) . '&' . rfc3986_encode($token_secret);
        $sig = base64_encode(hash_hmac('sha1', $base_string, $signature_key, true));
        return $sig;
    }

function oauth_http_build_query($params, $excludeOauthParams=false)
{
    $query_string = '';
    if (! empty($params)) {

        // rfc3986 encode both keys and values
        $keys = rfc3986_encode(array_keys($params));
        $values = rfc3986_encode(array_values($params));
        $params = array_combine($keys, $values);

        // Parameters are sorted by name, using lexicographical byte value ordering.
        // http://oauth.net/core/1.0/#rfc.section.9.1.1
        uksort($params, 'strcmp');

        // Turn params array into an array of "key=value" strings
        $kvpairs = array();
        foreach ($params as $k => $v) {
            if ($excludeOauthParams && substr($k, 0, 5) == 'oauth') {
                continue;
            }
            if (is_array($v)) {
                // If two or more parameters share the same name,
                // they are sorted by their value. OAuth Spec: 9.1.1 (1)
                natsort($v);
                foreach ($v as $value_for_same_key) {
                    array_push($kvpairs, ($k . '=' . $value_for_same_key));
                }
            } else {
                // For each parameter, the name is separated from the corresponding
                // value by an '=' character (ASCII code 61). OAuth Spec: 9.1.1 (2)
                array_push($kvpairs, ($k . '=' . $v));
            }
        }

        // Each name-value pair is separated by an '&' character, ASCII code 38.
        // OAuth Spec: 9.1.1 (2)
        $query_string = implode('&', $kvpairs);
    }

    return $query_string;
}

function rfc3986_encode($raw_input)
{
    if (is_array($raw_input)) {
        return array_map('rfc3986_encode', $raw_input);
    } else if (is_scalar($raw_input)) {
        return str_replace('%7E', '~', rawurlencode($raw_input));
    } else {
        return '';
    }
}

function signature_base_string($http_method, $url, $params)
{
    // Decompose and pull query params out of the url
    $query_str = parse_url($url, PHP_URL_QUERY);
    if ($query_str) {
        $parsed_query = oauth_parse_str($query_str);
        // merge params from the url with params array from caller
        $params = array_merge($params, $parsed_query);
    }

    // Remove oauth_signature from params array if present
    if (isset($params['oauth_signature'])) {
        unset($params['oauth_signature']);
    }

    // Create the signature base string. Yes, the $params are double encoded.
    $base_string = rfc3986_encode(strtoupper($http_method)) . '&' .
        rfc3986_encode(normalize_url($url)) . '&' .
        rfc3986_encode(oauth_http_build_query($params));



    return $base_string;
}

function normalize_url($url)
{
    $parts = parse_url($url);

    $scheme = $parts['scheme'];
    $host = $parts['host'];
    $port = '443';
    $path = $parts['path'];

    if (! $port) {
        $port = ($scheme == 'https') ? '443' : '80';
    }
    if (($scheme == 'https' && $port != '443')
        || ($scheme == 'http' && $port != '80')) {
        $host = "$host:$port";
    }

    return "$scheme://$host$path";
}


function oauth_parse_str($query_string)
{
    $query_array = array();

    if (isset($query_string)) {

        // Separate single string into an array of "key=value" strings
        $kvpairs = explode('&', $query_string);

        // Separate each "key=value" string into an array[key] = value
        foreach ($kvpairs as $pair) {
            list($k, $v) = explode('=', $pair, 2);

            // Handle the case where multiple values map to the same key
            // by pulling those values into an array themselves
            if (isset($query_array[$k])) {
                // If the existing value is a scalar, turn it into an array
                if (is_scalar($query_array[$k])) {
                    $query_array[$k] = array($query_array[$k]);
                }
                array_push($query_array[$k], $v);
            } else {
                $query_array[$k] = $v;
            }
        }
    }

    return $query_array;
}
类YahooCurl
{
公共$YahooRequestToken;
}
函数getYahooRequestToken()
{
$params=数组(
'oauth_nonce'=>urlencode(GeneratorDomainString()),
'oauth_timestamp'=>time(),
'oauth_consumer_key'=>config::yahooConsumerKey,
“oauth_签名_方法”=>“明文”,
“oauth_签名”=>配置::YahooConsumerCret。“%26”,
“oauth_版本”=>“1.0”,
'oauth_callback'=>config::yahooCallBackDomain);
$url='1https://api.login.yahoo.com/oauth/v2/get_request_token';
$postData='';
foreach($k=>v的参数){
$postData.=$k.'='.$v.'&';
}
rtrim($postData,&');
//var_dump($postData);
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$URL);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_头,false);
curl_setopt($ch,CURLOPT_POST,count($postData));
curl_setopt($ch,CURLOPT_POSTFIELDS,$postData);
$output=curl\u exec($ch);
卷曲关闭($ch);
返回$output;
}
函数生成器域字符串($length=6)
{
$characters='0123456789abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz';
$randomString='';
对于($i=0;$i<$length;$i++){
$randomString.=$characters[rand(0,strlen($characters)-1)];
}
返回$randomString;
}
函数getYahooAccessToken($oauthVerifier、$oauthToken、$oauthSecret)
{
$url='1https://api.login.yahoo.com/oauth/v2/get_token?oauth_consumer_key='.urlencode(配置::yahoosumerkey)。
“&oauth_signature_method=”.urlencode('plaintext')。
“&oauth_version=”.urlencode('1.0')。
“&oauth_验证器=”.urlencode($oauthVerifier)。
“&oauth_token=”.urlencode($oauthToken)。
“&oauth_timestamp=”.urlencode(time())。
“&oauth_nonce=”.urlencode(generateRandomString())。
“&oauth_签名=”.config::YahooConsumerCret.'%26'.$oauthSecret;
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$URL);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
//curl_setopt($ch,CURLOPT_头,false);
$output=curl\u exec($ch);
卷曲关闭($ch);
返回$output;
}
函数getYahooUser($userID、$oauthToken、$oauthSecret)
{
$ch=curl_init();
$url='1https://social.yahooapis.com/v1/user/“.$userID./profile”;
$params['oauth_consumer_key']=config::yahoosumerkey;
$params['oauth\u nonce']=generateRandomString();
$params['oauth\u签名\u方法]='HMAC-SHA1';
$params['oauth_timestamp']=time();
$params['oauth_token']=$oauthToken;
$params['oauth_version']='1.0';
$params['oauth_签名']=
oauth_compute_hmac_sig('GET',$url,$params,
配置::YahooConsumerCret,$oauthSecret);
$query\u parameter\u string=oauth\u http\u build\u query($params);
$request\u url=$url。($query\u参数\u字符串?
(“?”.$query_参数_字符串):“”);
curl_setopt($ch,CURLOPT_URL,$request_URL);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
$output=curl\u exec($ch);
变量转储(输出);
返回$output;
}
函数oauth_compute_hmac_sig($http_method、$url、$params、$consumer_secret、$token_secret)
{
$base\u string=签名\u base\u string($http\u方法,$url,$params);
$signature_key=rfc3986_encode($consumer_secret)。&'.rfc3986_encode($token_secret);
$sig=base64_编码(hash_hmac('sha1',$base_string,$signature_key,true));
返回$sig;
}
函数oauth_http_build_query($params,$excludeAuthParams=false)
{
$query_string='';
如果(!empty($params)){
//rfc3986对键和值进行编码
$keys=rfc3986_编码(数组_键($params));
$values=rfc3986_编码(数组_值($params));
$params=array_combine($key,$value);
//参数按名称排序,使用字典式字节值排序。
// http://oauth.net/core/1.0/#rfc.section.9.1.1
uksort($params,'strcmp');
//将params数组转换为“key=value”字符串数组
$kvpairs=array();
foreach($k=>v的参数){
if($excludeAuthParams&&substr($k,0,5)=='oauth'){
继续;
}
if(is_数组($v)){
//如果两个或多个参数共享同一名称,
//它们按值排序。OAuth规范:9.1.1(1)
纳索特(5美元);
foreach($v作为$value,用于相同的密钥){
数组推送($kvpairs,($k.'='.$value_表示相同的密钥));
}
}否则{
//对于每个参数,名称与相应的
//由“=”字符表示的值