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

如何用Django AllAuth已认证用户访问另一Google OAuth API

实现思路与方案

核心原理

第三方API验证Google Access Token的本质是:让第三方调用Google官方的令牌验证端点,确认令牌的有效性、受众范围、过期时间等核心信息,验证通过后即可信任该用户的身份。

步骤1:从Django AllAuth获取用户的Google Access Token

Django AllAuth会将用户的OAuth凭证存储在SocialAccount和SocialToken模型中,你可以通过当前登录用户关联的模型实例直接获取令牌:

from allauth.socialaccount.models import SocialAccount, SocialToken

def get_google_access_token(user):
    try:
        social_account = SocialAccount.objects.get(user=user, provider='google')
        token = SocialToken.objects.get(account=social_account)
        return token.token  # 返回当前有效的Google Access Token
    except (SocialAccount.DoesNotExist, SocialToken.DoesNotExist):
        return None

注意:AccessToken存在过期时间,AllAuth默认会自动刷新令牌(前提是你在Google Cloud Console配置了offline_access权限),因此获取到的令牌大概率处于有效状态。

步骤2:第三方API验证Google Token的具体实现

第三方API需按以下流程完成令牌验证:

  1. 接收前端传递的Google Access Token
  2. 调用Google的令牌验证端点,传入令牌参数:
    curl 'https://oauth2.googleapis.com/tokeninfo?access_token=USER_ACCESS_TOKEN'
    
  3. 解析响应结果,重点检查以下字段:
    • aud:必须与第三方API在Google Cloud Console注册的客户端ID完全匹配,确保令牌是颁发给你的应用的
    • exp:令牌过期时间戳,需确认当前时间未超过该值
    • sub:用户的唯一标识,可用于关联第三方API自身的用户记录

验证通过后,第三方API即可基于该用户标识提供对应服务。

更优方案:使用ID Token替代Access Token

相比Access Token,Google的ID Token(JWT格式)更适合身份验证场景:

  • 自身包含用户核心信息(邮箱、唯一ID、姓名等),无需额外调用Google API获取用户数据
  • 支持本地验证签名,无需每次请求Google的验证端点,大幅提升性能
  • 完全符合OAuth2 OpenID Connect规范,兼容性更强

获取ID Token的方法

在Django AllAuth的Google OAuth配置中,确保添加openid权限范围,AllAuth会自动获取ID Token并存储在SocialAccount的extra_data中:

def get_google_id_token(user):
    try:
        social_account = SocialAccount.objects.get(user=user, provider='google')
        return social_account.extra_data.get('id_token')
    except SocialAccount.DoesNotExist:
        return None

本地验证ID Token

第三方API可通过Google公钥验证ID Token的签名,示例代码如下:

import jwt
import requests

def verify_google_id_token(id_token, client_id):
    certs = requests.get('https://www.googleapis.com/oauth2/v3/certs').json()
    try:
        payload = jwt.decode(
            id_token,
            certs,
            algorithms=['RS256'],
            audience=client_id,
            options={"verify_exp": True}
        )
        return payload
    except jwt.InvalidTokenError:
        return None

验证通过后,payload中的sub字段是用户的唯一标识,email为用户邮箱,可直接用于关联第三方API的用户记录。

架构注意事项

  • 令牌安全:AccessToken和ID Token必须通过HTTPS传输,禁止明文传递
  • 权限配置:确保Django应用在Google OAuth中请求的权限范围包含第三方API所需的用户信息(如email、profile)
  • 过期处理:若使用AccessToken,需处理令牌过期的情况,AllAuth会自动刷新令牌,但需确保SocialToken中存储了refresh token
  • 用户关联:第三方API建议使用Google用户的sub字段作为唯一标识,避免依赖邮箱(用户可能修改邮箱地址)

内容的提问来源于stack exchange,提问作者Hervé LE BARS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:23:14