Google Calendar API权限持久化问题 - JavaScript实现
解决Google Calendar API网页端每次刷新需重新授权的问题
问题原因
官方文档提到的“授权信息存储在文件系统”是针对桌面端/服务器端的代码实现,而网页端运行在浏览器环境中,gapi默认仅将token保存在内存中,页面刷新后内存数据丢失,因此每次都需要重新请求授权。要实现持久化免授权,需要把token存储到浏览器的本地存储(localStorage)中。
解决方案
通过以下修改实现token的持久化:
- 登录成功后将token写入
localStorage - 页面初始化时从
localStorage读取token并恢复到gapi客户端 - 调整登录逻辑优先检查本地存储的有效token
- 登出时同步清除本地存储的token
修改后的完整代码
const CLIENT_ID = ''; const API_KEY = ''; const DISCOVERY_DOC = 'https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest'; const SCOPES = 'https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/calendar'; let tokenClient; let gapiInited = false; let gisInited = false; function gapiLoaded() { gapi.load('client', initializeGapiClient); } async function initializeGapiClient() { await gapi.client.init({ apiKey: API_KEY, discoveryDocs: [DISCOVERY_DOC], }); // 页面初始化时从localStorage恢复token const savedToken = localStorage.getItem('gapi-calendar-token'); if (savedToken) { gapi.client.setToken(JSON.parse(savedToken)); } gapiInited = true; } function gisLoaded() { tokenClient = google.accounts.oauth2.initTokenClient({ client_id: CLIENT_ID, scope: SCOPES, callback: '', // defined later }); gisInited = true; } //? Sign In function handleAuthClick() { tokenClient.callback = async (resp) => { if (resp.error !== undefined) { throw (resp); } // 登录成功后将token存入localStorage localStorage.setItem('gapi-calendar-token', JSON.stringify(gapi.client.getToken())); }; const currentToken = gapi.client.getToken(); if (!currentToken || currentToken.expires_at <= Date.now() / 1000) { // 无有效token时请求授权 tokenClient.requestAccessToken({prompt: currentToken ? '' : 'consent'}); } } //? Sign Out function handleSignoutClick() { console.log("sign out") const token = gapi.client.getToken(); if (token !== null) { google.accounts.oauth2.revoke(token.access_token); gapi.client.setToken(''); // 登出时清除localStorage中的token localStorage.removeItem('gapi-calendar-token'); } }
关键修改点说明
- 初始化恢复token:在
initializeGapiClient函数中,从localStorage读取保存的token并设置给gapi客户端 - 登录后保存token:在授权回调中,将获取到的token存入
localStorage - 登录逻辑优化:检查当前token是否存在且未过期,避免不必要的授权请求
- 登出同步清理:清除gapi内存中的token同时,删除
localStorage里的存储项
内容的提问来源于stack exchange,提问作者oiukuik hom
相关产品推荐
相关产品推荐

