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

如何基于请求头用户名(无密码)生成DRF认证令牌

解决DRF自定义ObtainAuthToken时用户名字符串无法关联Token的问题

你遇到的报错核心原因是Token.objects.get_or_create(user=user)要求传入User模型实例,但你从请求头拿到的user是字符串类型的用户名,两者类型不匹配。结合你的需求(内部用户无需暴露密码,用令牌调用API并识别调用者),可以通过以下方式解决:

核心思路

  1. 从请求头提取用户名后,先在系统中查询是否存在对应用户;如果不存在,自动创建一个内部用户(设置不可用的随机密码,避免用户通过该密码登录)
  2. 使用获取到的User对象来生成或获取唯一Token

修改后的完整代码

from django.contrib.auth.models import User
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
from django.contrib.auth.hashers import make_random_password

class CustomAuthToken(ObtainAuthToken):
  
    def get(self, request, *args, **kwargs):
        # 从请求头获取用户名
        username = request.META.get('USERINFO-cn')
        if not username:
            return Response({'error': '请求头未携带用户名'}, status=400)
        
        # 获取或创建内部用户:自动生成随机密码,确保用户无法通过该密码登录
        user, user_created = User.objects.get_or_create(
            username=username,
            defaults={'password': make_random_password()}
        )
        
        # 为用户生成或获取唯一令牌
        token, token_created = Token.objects.get_or_create(user=user)
        
        return Response({
            'token': token.key,
            'username': username,
            'user_id': user.id  # 返回用户ID,方便后续API识别调用者身份
        })

关键说明

  • 自动创建用户时使用make_random_password()生成随机密码,保证内部用户不会通过该密码登录系统,符合“无需暴露密码”的需求
  • 额外返回user_id是为了后续API更精准地识别调用者(用户名可能重复,但用户ID唯一)
  • 务必确保USERINFO-cn请求头是经过OAuth2认证后可靠传入的,防止恶意伪造用户名

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 23:18:17