Sign In With Google新版库如何后台刷新refresh token
使用Sign In With Google服务时如何刷新auth token
接入新版Sign In With Google后,默认签发的ID token有效期为30分钟,到期触发的手动确认登录流程会打断用户操作,甚至造成未保存的操作数据丢失。旧版Google身份认证库支持的后台静默刷新token能力,在新版GSI库中可通过以下方案实现,全程无需用户手动交互:
核心实现逻辑
新版GSI Web库没有单独暴露名为「刷新token」的独立API,静默刷新能力复用了One Tap授权的静默模式,只要用户浏览器保留有效Google登录态、且未撤销对你站点的授权,就可以无感知拉取到新的有效token。
具体实现步骤
- 不要等token完全过期再处理刷新逻辑,本地解析token拿到过期时间戳,提前5-10分钟触发刷新流程,此时静默刷新成功率接近100%
- 初始化GSI配置时,将
prompt参数设置为none,该配置会禁用所有可见的弹窗、提示,仅在后台发起授权请求 - 拿到新的凭证后更新本地存储的token和过期时间,后续接口请求直接使用新token即可
- 如果静默刷新返回失败,说明用户Google登录态失效/已撤销站点授权,此时再引导用户走显式登录流程即可,不会出现中途打断用户操作的问题
参考实现代码
// 解析JWT token工具方法 const parseJwt = (token) => { return JSON.parse(atob(token.split('.')[1])); }; // 静默刷新token核心方法 const silentRefreshGoogleToken = () => { return new Promise((resolve, reject) => { google.accounts.id.initialize({ client_id: '替换为你自己的Google客户端ID', callback: (credentialResponse) => { const newToken = credentialResponse.credential; const tokenPayload = parseJwt(newToken); // 更新本地存储的token和过期时间 localStorage.setItem('google_auth_token', newToken); localStorage.setItem('google_token_expire_at', tokenPayload.exp * 1000); resolve(newToken); }, prompt: 'none' // 关键配置:关闭所有可见交互,仅发起后台静默请求 }); google.accounts.id.prompt((notification) => { // 静默模式下请求完成未触发交互时判断结果 if (notification.isNotDisplayed() || notification.isSkippedMoment()) { const reason = notification.getNotDisplayedReason() || notification.getSkippedReason(); // 无有效登录态、用户撤销授权等场景视为刷新失败 if (['opt_out_or_no_session', 'user_cancel'].includes(reason)) { reject(new Error('Silent refresh failed, user need to login again')); } } }); }); }; // 定时检查token状态,自动触发刷新 const scheduleTokenRefresh = async () => { const expireAt = Number(localStorage.getItem('google_token_expire_at') || 0); const currentTime = Date.now(); // 距离过期不足10分钟时触发刷新 if (expireAt - currentTime < 10 * 60 * 1000) { try { await silentRefreshGoogleToken(); } catch (err) { // 此处处理需要用户重新登录的逻辑,比如在页面非侵入位置展示登录提示,不要直接弹弹窗打断用户 console.warn('Google auth token refresh failed, show unobtrusive login reminder'); } } }; // 页面加载时立即检查一次,之后每5分钟轮询检查 scheduleTokenRefresh(); setInterval(scheduleTokenRefresh, 5 * 60 * 1000);
注意事项
- 官方API文档中
prompt: 'none'的配置归类在One Tap交互的参数说明下,没有单独和token刷新关联说明,很容易被忽略,这是实现静默刷新的核心配置 - 不要在token过期后再调用刷新逻辑,token完全失效后静默刷新的成功率会明显下降
- 静默刷新失败时不要高频重试,只需要在用户后续主动触发登录相关操作时再走显式登录流程即可,避免不必要的资源消耗
内容的提问来源于stack exchange,提问作者Alexandre Kandalintsev
相关产品推荐
相关产品推荐

