![](/img/trans.png)
[英]Google OAuth2: "Error: No access, refresh token or API key is set" when trying to access Google Drive API
[英]Google OAuth2 API Refresh Tokens
我正在使用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%運行,直到令牌過期。 在此之后,我收到“Invalid Credentials”消息。
我的假設是,一旦令牌到期,刷新令牌將用於自動重新創建訪問令牌。 我錯過了什么嗎?
好的,所以我發現了getAccessToken
方法,它將檢查access_token
並使用它,除非它已經過期,在這種情況下它將使用refresh_token
來生成一個新的access_token
。
以下是使用刷新令牌獲取訪問令牌的更新解決方案:
const { google } = require("googleapis");
const OAuth2 = google.auth.OAuth2;
const oauth2Client = new OAuth2(
"xxxxxxxxx.apps.googleusercontent.com", // ClientID
"xxxxxxx", // Client Secret
"https://developers.google.com/oauthplayground" // Redirect URL
);
oauth2Client.setCredentials({
refresh_token:
"xxxxxxxx"
});
const accessToken = oauth2Client.getAccessToken();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.