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

drf-social-oauth2中JWT自定义声明及request.user匿名问题

解决drf-social-oauth2中自定义JWT声明时无法获取用户信息的问题

你遇到的核心问题是在重写TokenView.create_token_response时,request.user仍为AnonymousUser——这是因为该方法执行阶段,认证流程尚未将已验证的用户关联到当前request对象上。以下是两种可行的解决方案:

方案一:从原始JWT中提取用户ID并查询用户

原始生成的JWT令牌中已经包含用户身份标识(drf-social-oauth2默认是user_id字段),你可以解码原始令牌获取用户ID,再查询用户模型拿到所需信息:

from drf_social_oauth2.views import TokenView
import json
from jose import jwt
from django.conf import settings
from django.contrib.auth import get_user_model

User = get_user_model()

class CustomTokenView(TokenView):
    def create_token_response(self, request):
        response_data = super().create_token_response(request)
        url, headers, body, status = response_data
        
        # 仅处理成功获取令牌的情况
        if status == 200:
            token_data = json.loads(body)
            access_token = token_data.get("access_token")
            
            # 解码原始JWT,关闭过期验证(因为刚生成的令牌不会过期)
            decoded_token = jwt.decode(
                access_token, settings.SECRET_KEY, algorithms=["HS256"], options={"verify_exp": False}
            )
            # 从解码结果中获取用户ID
            user_id = decoded_token.get("user_id")
            user = User.objects.get(id=user_id)
            
            # 添加自定义声明
            decoded_token["custom_claim"] = "custom_value"
            decoded_token["username"] = user.username
            decoded_token["email"] = user.email
            
            # 重新编码JWT
            updated_access_token = jwt.encode(
                decoded_token, settings.SECRET_KEY, algorithm="HS256"
            )
            token_data["access_token"] = updated_access_token
            modified_body = json.dumps(token_data)
            return url, headers, modified_body, status
        
        return response_data

方案二:重写JWT Payload生成器(更优雅)

drf-social-oauth2支持通过配置自定义JWT Payload生成函数,这是官方推荐的扩展方式,无需重写视图:

  1. 在项目中创建工具文件(比如account/utils.py),添加自定义Payload处理函数:
from drf_social_oauth2.utils import default_jwt_payload_handler

def custom_jwt_payload_handler(user, issuer=None, audience=None, scope=None):
    # 先调用默认生成器获取基础payload
    payload = default_jwt_payload_handler(user, issuer, audience, scope)
    
    # 添加自定义声明
    payload["custom_claim"] = "custom_value"
    payload["username"] = user.username
    payload["email"] = user.email
    
    return payload
  1. 在settings.py中配置该函数:
# drf-social-oauth2 JWT配置
ACTIVATE_JWT = True
JWT_PAYLOAD_HANDLER = "account.utils.custom_jwt_payload_handler"

这种方式直接在JWT生成阶段注入自定义声明,能直接拿到已验证的用户对象,避免了手动查询用户的步骤,代码更简洁易维护。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 21:08:14