【发布时间】:2016-08-03 09:15:06
【问题描述】:
我正在使用google-auth-library-nodejs 库来集成到多个 GMail 帐户,以获取电子邮件列表。
我的流程很简单:
1) 尝试授权客户端,使用此功能:
function _authorise(mailBox, callback) {
let auth = new googleAuth();
let clientId = eval(`process.env.GMAIL_API_CLIENT_ID_${mailBox.toUpperCase()}`);
let clientSecret = eval(`process.env.GMAIL_API_CLIENT_SECRET_${mailBox.toUpperCase()}`);
let redirectUri = eval(`process.env.GMAIL_API_REDIRECT_URI_${mailBox.toUpperCase()}`);
let tokenFile = process.env.GMAIL_API_TOKEN_PATH + mailBox.toLowerCase()+ process.env.GMAIL_API_TOKEN_BASE_FILE_NAME;
let oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUri);
fs.readFile(tokenFile, ((err, token) => {
if (err) {
_getNewToken(mailBox,oauth2Client,callback);
} else {
oauth2Client.credentials = JSON.parse(token);
callback(oauth2Client);
}
}))
}
2) 该方法将检查文件中是否存在令牌。如果找不到文件,以下函数将创建该文件:
function _getNewToken(mailBox, oauth2Client, callback) {
var authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: process.env.GMAIL_API_SCOPES
});
console.log('To authorize this app, please use this url: ', authUrl);
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('Enter the code from that page here: ', ((code) => {
rl.close();
oauth2Client.getToken(code, function(err, token) {
if (err) {
console.log('Error while trying to retrieve access token', err);
return;
}
oauth2Client.credentials = token;
_storeToken(mailBox,token);
callback(oauth2Client);
});
}));
}
function _storeToken(mailBox, token) {
let tokenFile = process.env.GMAIL_API_TOKEN_PATH + mailBox.toLowerCase()+ process.env.GMAIL_API_TOKEN_BASE_FILE_NAME;
fs.writeFile(tokenFile, JSON.stringify(token));
}
我使用https://www.googleapis.com/auth/gmail.readonly 作为范围。
以下是创建的文件示例:
{"access_token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","token_type":"Bearer","refresh_token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","expiry_date":1460509994081}
处理后,这里是返回的 auth 对象的示例:
OAuth2Client {
transporter: DefaultTransporter {},
clientId_: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
clientSecret_: 'xxxxxxxxxxxxxxxxxxxxxxxx',
redirectUri_: 'urn:ietf:wg:oauth:2.0:oob',
opts: {},
credentials: {
access_token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
token_type: 'Bearer',
refresh_token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
expiry_date: 1460509994081
}
}
如果我删除文件,并通过手动同意过程,则身份验证工作 100%,直到令牌过期。在此之后,我收到“无效凭据”消息。
我的假设是,一旦令牌过期,刷新令牌将用于自动重新创建访问令牌。我错过了什么吗?
【问题讨论】:
-
如果您请求用户访问并获得新的刷新令牌,您是否保存它?在它们停止工作并且您获得无效凭据之后,您只能通过 google 进行 25 次有效的刷新。
-
@DaImTo,是的,我怀疑这是 25 限制。我不明白的是刷新令牌到底是什么时候重新发出的。
-
我刚刚刷新了访问令牌,然后我得到了一个新的 access_token、一个新的 refresh_token 和一个新的 expiry_date。有效期为 1 小时。所以,我的假设是在 1 小时到期窗口之后,refresh_token 将用于自动创建一个新的 access_token。那是对的吗?或者 refresh_token 是否会在 1 小时后重新生成?
-
当用户单击接受身份验证时会重新发出刷新令牌。如果访问令牌已过期,则刷新令牌将用于从身份验证服务器获取新的访问令牌。我不熟悉 nod 客户端库的内部工作原理,但我认为它应该为您处理所有这些。
-
@DaImTo,这是一个服务器到服务器的应用程序,即我的 API 使用上面的代码连接到 Google 的 Auth 服务器。我必须接受身份验证的唯一一次是当我必须通过将来自 Google 的 URL 粘贴到浏览器中并取回代码来完成该过程时。我很有可能在测试期间超过了 25 个限制。有没有办法重置这些刷新令牌?
标签: node.js google-api google-api-nodejs-client oauth2