我已经在这里阅读了各种其他主题,似乎找不到一个真正给出令人信服的答案。
我一直关注https://developer.yahoo.com/oauth/guide/oauth-accesstoken.html处的文档,现在为我提供了一套很好的凭据和用户ID,无论谁登录。到目前为止,我一直在使用https和明文方法签名。
现在我希望收到有关用户的一些信息,并且必须使用HMACS-SHA1方法签署我的请求。
基本上,像这里的许多其他人一样,我收到了Please提供的有效凭据。 OAuth oauth_problem =" signature_invalid",realm =" yahooapis.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;
}
有没有人知道我做错了什么?
答案 0 :(得分:2)
说真的,雅虎api令人震惊......
Ok使用https://github.com/joechung/oauth_yahoo提供的Joe Chungs oauth示例和来自雅虎开发者网络https://developer.yahoo.com/forum/OAuth-General-Discussion-YDN-SDKs/token-rejected/1259915145000-8648ab55-f852-38ed-91c9-bf7e37f7d76c
的帖子解决了问题诀窍是在你的签名创建中添加它之前对你从gettoken请求获得的auth令牌进行url解码。
这是我完整的雅虎功能,如果您遇到同样的问题,那么只需在我的配置中包含您的变量:: 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;
}
希望这有助于某人。