使用 OAuth2 的 Yahoo Fantasy Sports 示例
Yahoo Fantasy Sports example using OAuth2
我想构建一个应用程序来查询我的 Yahoo! 中的数据。 Fantasy league 但无法通过 3-legged OAuth 身份验证,希望有人能给我一个快速演示,或者给我指点相关教程。
我愿意使用 NodeJS,Python 或 PHP。
我已经注册了一个 API 并获得了消费者密钥和消费者秘密。
Their documentation contains two PHP examples (that I couldn't get to work) and references OAuth.net's list of libaries.
但是让我们来看看 Python。 rauth documentation 只列出
第一条腿,我应该如何完成其他两条腿?
from rauth import OAuth2Service
yahoo = OAuth2Service(
client_id='mykey',
client_secret='mysecret',
name='yahoo',
authorize_url='https://api.login.yahoo.com/oauth/v2/request_auth',
access_token_url='https://api.login.yahoo.com/oauth/v2/get_token',
base_url='https://api.login.yahoo.com/oauth/v2/')
url = yahoo.get_authorize_url()
我在 GitHub.com 上找到的几乎所有示例都已有多年历史并且存在兼容性问题,尽管 yahoofantasysandbox 似乎几乎存在。
This tutorial recommens using fantasy-sports 但我没有看到很多关于实现或示例的细节。
有人可以为我指出正确的方向或给我一个工作代码演示吗?
一年后,我自己做到了。
TL;DR:如果你想访问 Yahoo Fantasy API 只需使用我创建的这个 NodeJS 工具:https://github.com/edwarddistel/yahoo-fantasy-baseball-reader
如果您想在 NodeJS 或 PHP 中创建自己的应用程序,方法如下:
去https://developer.yahoo.com/apps/create/,得到一个Consumer Key
和Consumer Secret
将Consumer Key
填入https://api.login.yahoo.com/oauth2/request_auth?client_id=YOUR-CONSUMER-KEY-GOES-HERE&redirect_uri=oob&response_type=code&language=en-us并同意允许访问,然后获取授权码
构造Auth头,CONSUMER_KEY:CONSUMER_SECRET的Base64编码:
const AUTH_HEADER = Buffer.from(`${CONSUMER_KEY}:${CONSUMER_SECRET}`, `binary`).toString(`base64`);
Yahoo 需要 x-www-form-urlencoded
,所以如果使用像 Axios you'll need to stringify the data as per the docs
这样的 HTTP 请求库
向雅虎提出请求。这是一个例子:
function getInitialAuthorization () {
return axios({
url: `https://api.login.yahoo.com/oauth2/get_token`,
method: 'post',
headers: {
'Authorization': `Basic ${AUTH_HEADER}`,
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
},
data: qs.stringify({
client_id: CONSUMER_KEY,
client_secret: CONSUMER_SECRET,
redirect_uri: 'oob',
code: YAHOO_AUTH_CODE,
grant_type: 'authorization_code'
}),
timeout: 1000,
}).catch((err) => {
console.error(`Error in getInitialAuthorization(): ${err}`);
});
}
获取该响应并将其写入文件。每使用 60 分钟,您将需要这些凭据来重新授权该应用程序。
向 Yahoo API 发出正常的 HTTP 请求。检查响应,如果授权令牌已过期,请使用一组略有不同的参数重新授权:
function refreshAuthorizationToken (token) {
return axios({
url: `https://api.login.yahoo.com/oauth2/get_token`,
method: 'post',
headers: {
'Authorization': `Basic ${AUTH_HEADER}`,
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
},
data: qs.stringify({
redirect_uri: 'oob',
grant_type: 'refresh_token',
refresh_token: token
}),
timeout: 10000,
}).catch((err) => {
console.error(`Error in refreshAuthorizationToken(): ${err}`);
});
}
- 发出API请求并检查授权的示例:
// Hit the Yahoo Fantasy API
async function makeAPIrequest (url) {
let response;
try {
response = await axios({
url: url,
method: 'get',
headers: {
'Authorization': `Bearer ${CREDENTIALS.access_token}`,
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
},
timeout: 10000,
});
const jsonData = JSON.parse(parser.toJson(response.data));
return jsonData;
} catch (err) {
if (err.response.data && err.response.data.error && err.response.data.error.description && err.response.data.error.description.includes("token_expired")) {
const newToken = await refreshAuthorizationToken(CREDENTIALS.refresh_token);
if (newToken && newToken.data && newToken.data.access_token) {
CREDENTIALS = newToken.data;
// Just a wrapper for fs.writeFile
writeToFile(JSON.stringify(newToken.data), AUTH_FILE, 'w');
return makeAPIrequest(url, newToken.data.access_token, newToken.data.refresh_token);
}
} else {
console.error(`Error with credentials in makeAPIrequest()/refreshAuthorizationToken(): ${err}`);
process.exit();
}
}
}
下面是 PHP 中的示例:
function getInitialAuthorizationToken() {
$ch = curl_init();
$post_values = [
"client_id" => $GLOBALS['consumer_key'],
"client_secret" => $GLOBALS['consumer_secret'],
"redirect_uri" => "oob",
"code" => $GLOBALS['initial_auth_code'],
"grant_type" => "authorization_code"
];
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $GLOBALS['auth_endpoint'],
CURLOPT_POST => 1,
CURLOPT_HTTPHEADER => array(
'Authorization: Basic ' . $GLOBALS['auth_header'],
'Content-Type: application/x-www-form-urlencoded',
'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'),
CURLOPT_POSTFIELDS => http_build_query($post_values)
));
$answer = curl_exec($ch);
if (isset($answer)) writeToFile($answer);
if (!isset($access_token)) {
echo "Error!";
die;
}
else {
return $token;
}
}
希望这对其他人有帮助。
我想构建一个应用程序来查询我的 Yahoo! 中的数据。 Fantasy league 但无法通过 3-legged OAuth 身份验证,希望有人能给我一个快速演示,或者给我指点相关教程。
我愿意使用 NodeJS,Python 或 PHP。
我已经注册了一个 API 并获得了消费者密钥和消费者秘密。
Their documentation contains two PHP examples (that I couldn't get to work) and references OAuth.net's list of libaries.
但是让我们来看看 Python。 rauth documentation 只列出 第一条腿,我应该如何完成其他两条腿?
from rauth import OAuth2Service
yahoo = OAuth2Service(
client_id='mykey',
client_secret='mysecret',
name='yahoo',
authorize_url='https://api.login.yahoo.com/oauth/v2/request_auth',
access_token_url='https://api.login.yahoo.com/oauth/v2/get_token',
base_url='https://api.login.yahoo.com/oauth/v2/')
url = yahoo.get_authorize_url()
我在 GitHub.com 上找到的几乎所有示例都已有多年历史并且存在兼容性问题,尽管 yahoofantasysandbox 似乎几乎存在。
This tutorial recommens using fantasy-sports 但我没有看到很多关于实现或示例的细节。
有人可以为我指出正确的方向或给我一个工作代码演示吗?
一年后,我自己做到了。
TL;DR:如果你想访问 Yahoo Fantasy API 只需使用我创建的这个 NodeJS 工具:https://github.com/edwarddistel/yahoo-fantasy-baseball-reader
如果您想在 NodeJS 或 PHP 中创建自己的应用程序,方法如下:
去https://developer.yahoo.com/apps/create/,得到一个
Consumer Key
和Consumer Secret
将
Consumer Key
填入https://api.login.yahoo.com/oauth2/request_auth?client_id=YOUR-CONSUMER-KEY-GOES-HERE&redirect_uri=oob&response_type=code&language=en-us并同意允许访问,然后获取授权码构造Auth头,CONSUMER_KEY:CONSUMER_SECRET的Base64编码:
const AUTH_HEADER = Buffer.from(`${CONSUMER_KEY}:${CONSUMER_SECRET}`, `binary`).toString(`base64`);
Yahoo 需要
x-www-form-urlencoded
,所以如果使用像 Axios you'll need to stringify the data as per the docs 这样的 HTTP 请求库
向雅虎提出请求。这是一个例子:
function getInitialAuthorization () {
return axios({
url: `https://api.login.yahoo.com/oauth2/get_token`,
method: 'post',
headers: {
'Authorization': `Basic ${AUTH_HEADER}`,
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
},
data: qs.stringify({
client_id: CONSUMER_KEY,
client_secret: CONSUMER_SECRET,
redirect_uri: 'oob',
code: YAHOO_AUTH_CODE,
grant_type: 'authorization_code'
}),
timeout: 1000,
}).catch((err) => {
console.error(`Error in getInitialAuthorization(): ${err}`);
});
}
获取该响应并将其写入文件。每使用 60 分钟,您将需要这些凭据来重新授权该应用程序。
向 Yahoo API 发出正常的 HTTP 请求。检查响应,如果授权令牌已过期,请使用一组略有不同的参数重新授权:
function refreshAuthorizationToken (token) {
return axios({
url: `https://api.login.yahoo.com/oauth2/get_token`,
method: 'post',
headers: {
'Authorization': `Basic ${AUTH_HEADER}`,
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
},
data: qs.stringify({
redirect_uri: 'oob',
grant_type: 'refresh_token',
refresh_token: token
}),
timeout: 10000,
}).catch((err) => {
console.error(`Error in refreshAuthorizationToken(): ${err}`);
});
}
- 发出API请求并检查授权的示例:
// Hit the Yahoo Fantasy API
async function makeAPIrequest (url) {
let response;
try {
response = await axios({
url: url,
method: 'get',
headers: {
'Authorization': `Bearer ${CREDENTIALS.access_token}`,
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36',
},
timeout: 10000,
});
const jsonData = JSON.parse(parser.toJson(response.data));
return jsonData;
} catch (err) {
if (err.response.data && err.response.data.error && err.response.data.error.description && err.response.data.error.description.includes("token_expired")) {
const newToken = await refreshAuthorizationToken(CREDENTIALS.refresh_token);
if (newToken && newToken.data && newToken.data.access_token) {
CREDENTIALS = newToken.data;
// Just a wrapper for fs.writeFile
writeToFile(JSON.stringify(newToken.data), AUTH_FILE, 'w');
return makeAPIrequest(url, newToken.data.access_token, newToken.data.refresh_token);
}
} else {
console.error(`Error with credentials in makeAPIrequest()/refreshAuthorizationToken(): ${err}`);
process.exit();
}
}
}
下面是 PHP 中的示例:
function getInitialAuthorizationToken() {
$ch = curl_init();
$post_values = [
"client_id" => $GLOBALS['consumer_key'],
"client_secret" => $GLOBALS['consumer_secret'],
"redirect_uri" => "oob",
"code" => $GLOBALS['initial_auth_code'],
"grant_type" => "authorization_code"
];
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $GLOBALS['auth_endpoint'],
CURLOPT_POST => 1,
CURLOPT_HTTPHEADER => array(
'Authorization: Basic ' . $GLOBALS['auth_header'],
'Content-Type: application/x-www-form-urlencoded',
'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'),
CURLOPT_POSTFIELDS => http_build_query($post_values)
));
$answer = curl_exec($ch);
if (isset($answer)) writeToFile($answer);
if (!isset($access_token)) {
echo "Error!";
die;
}
else {
return $token;
}
}
希望这对其他人有帮助。