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

Python Django中Google OAuth2令牌过期后仍有效是什么原因?

问题根因

  • 时区不匹配导致credentials.expired判断失效
    Google OAuth返回的credentials.expiry是UTC时区的datetime对象,你存到数据库的时候用strftime转成了不带时区信息的字符串,从数据库读取后重建credentials实例时,如果init_creds_instance函数将该字符串转成了本地时区的datetime,就会导致时间比对出现偏差:实际已经过期的UTC时间,会被判定为还未到过期时间,所以永远走不到你写的刷新分支。
  • API请求未报错是Google客户端库自动刷新导致的
    你手动校验过期token返回无效,但是调用Google API正常,是因为google-api-python-client库本身内置了令牌有效性校验和自动刷新逻辑:当你传入的credentials带有refresh_token时,库在发起请求前会自动判断令牌是否过期,如果过期会自动调用刷新接口获取新的access_token再发起请求,所以不会抛出错误,和你自己写的google_oauth_check_token逻辑无关。
  • 数据库更新逻辑存在两处错误
    你当前google_oauth_check_token函数里的更新代码:
    1. 过滤条件写错:SystemServiceTokens.objects.filter(id=user_id)中的id是SystemServiceTokens表的主键,不是用户外键,应该改成filter(user_id=user_id)才能命中对应用户的凭证记录
    2. 只更新了access_token,没有同步更新expires_at字段,就算刷新逻辑生效,下次从数据库读取的还是旧的过期时间,判断逻辑还是会出错。

修复方案

  1. 存储和读取expires_at时统一使用UTC时区,不要丢失时区信息,或者直接存储令牌过期的时间戳(整数),避免时区转换错误
  2. 修正google_oauth_check_token中的数据库更新逻辑,刷新令牌后同步更新token和expires_at两个字段,调整正确的过滤条件
  3. 如果需要自己控制刷新逻辑,可以给客户端库的build方法传入cache_discovery=False,避免库的自动逻辑干扰你的测试。

内容的提问来源于stack exchange,提问作者Anna

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 11:21:01