You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:35:22