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

OAuth2 Code已被兑换错误及Django Auth ADFS用户信息获取问题

解决“OAuth2 Code已被兑换”及无用户信息问题

为什么Bearer Token中没有用户信息

  • client_credentials授权模式是应用级别的身份验证,获取的token代表你的Django应用本身,而非具体用户,所以token里不会包含用户个人信息。这种模式适合不需要用户上下文的后台操作,不适合需要用户身份的场景。

解决“OAuth2 Code已被兑换”的方案

因为Django Auth ADFS已经自动完成了code兑换流程,重复使用同一个code会触发微软的防重复兑换机制。你可以通过以下几种方式绕过这个限制:

1. 从Django Auth ADFS获取已兑换的用户token

Django Auth ADFS在完成认证后,会将用户的access token存储在用户会话或相关模型中。你可以直接从库提供的接口获取:

# 从request对象中获取已存储的access token
def get_user_access_token(request):
    if hasattr(request, 'adfs_access_token'):
        return request.adfs_access_token
    # 或者从session中读取(取决于库的配置)
    return request.session.get('adfs_access_token')

拿到这个token后,直接用它调用Microsoft Graph API就能获取用户信息。

2. 配置Django Auth ADFS请求额外的token或权限

修改Django Auth ADFS的配置,让它在认证过程中请求offline_access scope,这样会同时返回refresh token。之后你可以用refresh token去获取新的access token,无需重复使用authorization code:

# settings.py中的ADFS配置
ADFS = {
    'CLIENT_ID': '你的客户端ID',
    'CLIENT_SECRET': '你的客户端密钥',
    'SCOPE': ['openid', 'email', 'profile', 'https://graph.microsoft.com/.default', 'offline_access'],
    # 其他配置...
}

获取refresh token后,调用token端点刷新access token:

def refresh_access_token(refresh_token):
    token_url = "https://login.microsoftonline.com/你的租户ID/oauth2/v2.0/token"
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    token_data = {
        'grant_type': 'refresh_token',
        'refresh_token': refresh_token,
        'client_id': '你的客户端ID',
        'client_secret': '你的客户端密钥',
        'scope': 'https://graph.microsoft.com/.default'
    }
    response = requests.post(token_url, headers=headers, data=token_data)
    return response.json().get('access_token')

3. 让Django Auth ADFS直接返回用户信息

配置Django Auth ADFS的USERINFO_ENDPOINT,让它在认证时自动获取并存储用户信息,这样你无需再调用Graph API:

# settings.py中的ADFS配置
ADFS = {
    # 其他配置...
    'USERINFO_ENDPOINT': 'https://login.microsoftonline.com/你的租户ID/openid/userinfo',
    'CLAIM_MAPPING': {
        'first_name': 'given_name',
        'last_name': 'family_name',
        'email': 'email',
    },
}

之后可以直接从request.user对象中获取用户信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:40:11