Node.js开发Google Calendar应用遇权限错误:未设置访问/刷新令牌或API密钥
问题:Node.js Google Calendar 应用报错
Error: No access, refresh token or API key is set. 我正在使用Node.js开发一款访问Google Calendar的应用,遵循了Google官方的快速入门步骤,但运行时出现错误:Error: Error: No access, refresh token or API key is set.。
我已完成以下操作:
- 创建了凭证;
- 下载了JSON文件并重命名为
client_secret.json,放置在应用目录中。
以下是我的代码:
const fs = require('fs'); const readline = require('readline'); const {google} = require('googleapis'); const OAuth2Client = google.auth.OAuth2; const SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']; const TOKEN_PATH = './client_secret.json'; try { const content = fs.readFileSync('client_secret.json'); authorize(JSON.parse(content), listEvents); } catch (err) { return console.log('Error loading client secret file:', err); } function authorize(credentials, callback) { const {client_secret, client_id, redirect_uris} = credentials.installed; let token = {}; const oAuth2Client = new OAuth2Client(client_id, client_secret, redirect_uris[0]); // Check if we have previously stored a token. try { token = fs.readFileSync(TOKEN_PATH); } catch (err) { return getAccessToken(oAuth2Client, callback); } oAuth2Client.setCredentials(JSON.parse(token)); callback(oAuth2Client); } function getAccessToken(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 callback(err); oAuth2Client.setCredentials(token); // Store the token to disk for later program executions try { fs.writeFileSync(TOKEN_PATH, JSON.stringify(token)); console.log('Token stored to', TOKEN_PATH); } catch (err) { console.error(err); } callback(oAuth2Client); }); }); } function listEvents(auth) { const calendar = google.calendar({version: 'v3', auth}); calendar.events.list({ calendarId: 'primary', timeMin: (new Date()).toISOString(), maxResults: 10, singleEvents: true, orderBy: 'startTime', }, (err, {data}) => { if (err) return console.log('The API returned an error: ' + err); const events = data.items; if (events.length) { console.log('Upcoming 10 events:'); events.map((event, i) => { const start = event.start.dateTime || event.start.date; console.log(`${start} - ${event.summary}`); }); } else { console.log('No upcoming events found.'); } }); }
解决思路
一眼就揪出问题啦——你把凭证文件和token文件用了同一个路径!
看代码里这行:
const TOKEN_PATH = './client_secret.json';
第一次运行时,程序找不到token会触发授权流程,但当你输入授权码后,程序会把获取到的token直接写入client_secret.json,把原本的凭证文件彻底覆盖了!
第二次运行时,程序读取的client_secret.json已经是token内容,authorize函数里尝试从credentials.installed取client_id、client_secret这些字段自然取不到,OAuth2Client没有正确设置凭证,调用API时就抛出了那个错误。
具体修复步骤:
- 恢复凭证文件:重新从Google Cloud Console下载凭证JSON,重命名为
client_secret.json放回项目目录。 - 修改TOKEN_PATH:把token文件路径改成另一个独立的名字,比如
token.json:const TOKEN_PATH = './token.json'; - 重新运行程序:这次程序会正常引导你完成授权,token会被写入
token.json,再也不会覆盖凭证文件了。
额外提个小建议:记得把client_secret.json加入.gitignore,别不小心把敏感凭证提交到代码仓库里哦。
内容的提问来源于stack exchange,提问作者Bruno Araújo
相关产品推荐
相关产品推荐

