尝试将OAuth用于本地Node.js脚本时,我遇到了一些奇怪的行为。我现在的目标是在用户授权我的项目时从用户处获取刷新令牌。
我尽可能多地依赖Google的图书馆,但我仍然遇到问题。
当我尝试运行设置时,我正确地获取了OAuth页面并创建了一个授权令牌:
const { google } = require('googleapis');
const oauth2Client = new google.auth.OAuth2(
clientId,
clientSecret,
'urn:ietf:wg:oauth:2.0:oob'
);
const scopes = [
'https://www.googleapis.com/auth/calendar'
];
我在控制台中为用户提供了URL:
const url = oauth2Client.generateAuthUrl({
// 'online' (default) or 'offline' (gets refresh_token)
access_type: 'offline',
// If you only need one scope you can pass it as a string
scope: scopes
});
console.log(url);
然后我打开URL并生成令牌。我提示用户提供此值:
stdio.question('Authorization code', (err, code) => {
// Use this code to obtain a refresh token
console.log("CODE", code);
oauth2Client.getToken(code, (err, tokens) => {
console.log(err, tokens);
});
});
当我到达这一点时,我遇到了一个错误:
error: 'invalid_grant', error_description: 'Bad Request'
目前尚不清楚这是哪里出错。
如果我使用相同的身份验证令牌并使用cURL,它实际上按预期工作,所以就我所知,这不是配置错误。
curl -s -X POST -d 'code='$CODE'&client_id='$CLIENT_ID'&client_secret='$CLIENT_SECRET'&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code' https://www.googleapis.com/oauth2/v4/token
{
"access_token": "ACCESS",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "REFRESH"
}
更有趣的是,如果我通过流程并获得错误,尝试运行cURL命令将返回一个错误,表明请求已在某种程度上被接受:
{
"error": "invalid_grant",
"error_description": "Code was already redeemed."
}
这个OAuth库中发生了什么导致cURL没有发生无效授权问题,我该怎么做才能纠正Node.js代码?
答案 0 :(得分:0)
事实证明,stdio
库的一个问题是,在您收到回调之前,您输入的所有文字最终都是converted to lowercase。这导致invalid_grant
错误。
更好的方法是使用Node.js中的内置readline
模块
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Authorization code: ', (code) => {
// Use this code to obtain a refresh token
console.log("CODE", code);
oauth2Client.getToken(code, (err, tokens) => {
console.log(err, tokens);
rl.close();
});
});