【发布时间】:2023-03-23 00:33:02
【问题描述】:
我正在开发一个基本的应用程序,它只是读取来自特定 gmail 帐户(比如 fakeEmail@gmail.com)的电子邮件。首次运行时,该应用程序被授予阅读 fakeEmail@gmail.com 电子邮件的权限。并且 access_token、expiry_date(1 小时)和 refresh_token 等被保存到 'token.json' 文件中。
在访问令牌过期后的后续运行中,我确实没有看到正在发出刷新令牌请求,但该应用程序能够获取和读取来自 fakeEmail@gmail.com 的电子邮件。
该应用程序以 'node app.js' 的形式从命令行运行,它获取具有特定标签的电子邮件并在控制台上打印电子邮件的内容。
authorize() 方法是应用程序每次运行时调用的第一个方法。 getNewToken() 仅在第一次运行时调用并创建一个 'token.json' 文件,此时用户 fakeEmail@gmail.com 授予 App 读取其电子邮件的权限.
这是这个简单应用的相关代码:
const SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];
const TOKEN_PATH = 'token.json';
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
function authorize(credentials, callback) {
const {client_secret, client_id, redirect_uris} = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getNewToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);
});
}
function getNewToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err)
return console.error('Error retrieving access token', err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
function startApp(){
fs.readFile('gmailCredentials.json', (err, content) => {
if (err)
return console.log('Error loading client secret file:', err);
authorize(JSON.parse(content), function(auth){
checkForMailsWithLabel(auth, strLabel, function(err, res){
console.log("auth holds: " + util.inspect(auth) );
// this prints the same accessToken and expiration as the one we have in 'token.json'
// Even though the token is expired, the app is still able to read the emails
});
});
});
}
您在此处看到的代码几乎与他们在 github 上的示例完全相同:https://github.com/gsuitedevs/node-samples/blob/master/gmail/quickstart/index.js
如果重要的话,我还没有通过谷歌完成这个应用程序的验证过程。由于我正在使用自己的电子邮件帐户进行测试,因此在授予权限时出现不受信任的警告目前不是问题。
我的问题/假设是 googleapi 库将检查访问令牌是否已过期,如果已过期,它将自动请求另一个令牌并将其写入 '令牌。 json' 文件。
但据我所知,运行此代码时,'token.json' 文件是在第一次运行时创建的。即使 expiry_date(1 小时)已过期,谷歌图书馆也不会请求另一个令牌。我这样说是因为:
- 我没有看到“token.json”的任何更新
- 即使在成功提取电子邮件后,用于提取的令牌仍具有相同的访问令牌和过期时间。
我可以编写代码来检查 expiry_date 是否已过,并可能强制刷新 access_token。但这并不能解释为什么我的应用能够使用过期令牌获取电子邮件。
我宁愿使用推荐的方法,如果应该让库处理令牌。
请指教,我在这里缺少什么。
【问题讨论】:
标签: node.js google-api gmail-api