Google GIS登录迁移后JWT令牌1小时过期,如何获取刷新令牌?
解决方案:获取Google GIS的Refresh Token以续期身份令牌
Google GIS默认返回的ID Token(即你所说的JWT)仅1小时有效期,且本身不支持直接刷新——因为它是用于身份验证的短期令牌。要实现自动续期,你需要切换到OAuth 2.0授权码流,而非当前的纯ID Token验证流程,具体步骤如下:
一、前端调整:启用授权码模式并请求离线权限
前端需要修改Google登录的初始化逻辑,指定response_type: 'code'并添加access_type: 'offline'参数(这是获取refresh token的核心):
google.accounts.oauth2.initCodeClient({ client_id: '你的客户端ID', scope: 'openid email profile', ux_mode: 'popup', // 或'redirect',需与后端重定向URI匹配 access_type: 'offline', // 必须添加,告知Google需要离线访问权限 callback: (response) => { // 将授权码code发送到后端服务器 fetch('/api/google-auth', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code: response.code }) }); } });
二、后端(Python)修改:兑换授权码并存储Refresh Token
后端不再直接验证ID Token,而是用前端传来的授权码向Google兑换包含refresh token的凭证包,示例基于google-auth和google-auth-oauthlib库:
from google.oauth2 import id_token from google.auth.transport import requests from google_auth_oauthlib.flow import Flow from google.oauth2.credentials import Credentials # 配置信息,从Google Cloud控制台获取 CLIENT_ID = '你的客户端ID' CLIENT_SECRET = '你的客户端密钥' REDIRECT_URI = '你的重定向URI' # 需与前端ux_mode对应,如前端页面URL def exchange_code_for_tokens(auth_code): # 初始化授权流 flow = Flow.from_client_config( { "web": { "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "redirect_uris": [REDIRECT_URI], "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", } }, scopes=['openid', 'email', 'profile'] ) flow.redirect_uri = REDIRECT_URI # 用授权码兑换令牌 credentials = flow.fetch_token(code=auth_code) # 提取所需令牌 id_token_jwt = credentials.id_token # 原JWT身份令牌 access_token = credentials.access_token # API访问令牌 refresh_token = credentials.refresh_token # 刷新令牌,仅首次授权返回 # 可选:验证ID Token有效性 id_info = id_token.verify_oauth2_token( id_token_jwt, requests.Request(), CLIENT_ID ) # 将refresh_token与用户关联,持久化存储到数据库 save_refresh_token_to_db(user_id=id_info['sub'], refresh_token=refresh_token) return id_token_jwt, access_token def refresh_user_tokens(stored_refresh_token): # 使用refresh_token刷新获取新的ID Token和access_token creds = Credentials( None, refresh_token=stored_refresh_token, client_id=CLIENT_ID, client_secret=CLIENT_SECRET, token_uri="https://oauth2.googleapis.com/token" ) creds.refresh(requests.Request()) return creds.id_token, creds.access_token
关键注意事项
access_type: 'offline'是必填项,否则Google不会返回refresh token。- refresh token仅在用户首次授权时返回,后续重复授权不会再次返回(除非用户取消了应用权限),因此必须将其与用户绑定并持久化存储。
- 若用户取消应用权限,refresh token会失效,此时需引导用户重新登录授权。
- 确保Google Cloud项目中,OAuth 2.0客户端ID的授权来源和重定向URI配置正确,否则会触发权限错误。
内容的提问来源于stack exchange,提问作者Nandha MV
相关产品推荐
相关产品推荐

