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

如何修复Django REST Framework中"detail":"Invalid Token"报错问题

问题排查与修复方案

1. 核心报错原因:认证类执行顺序问题

DRF的认证逻辑优先级高于权限校验逻辑,若你在settings.py的REST_FRAMEWORK配置中全局开启了TokenAuthentication作为默认认证类,即使接口配置了AllowAny权限,只要请求携带了错误/过期的Token,会优先返回Invalid Token错误,完全不会进入接口逻辑。

修复方案:

给登录、注册接口显式指定空的认证类列表,跳过Token校验:

# 给AuthViewSet的login、register装饰器补充authentication_classes参数
@action(methods=['POST', ], detail=False, authentication_classes=[])
def login(self, request):
    # 原有逻辑保持不变

@action(methods=['POST', ], detail=False, authentication_classes=[])
def register(self, request):
    # 原有逻辑保持不变

测试时先清空请求头里的Token字段,不带Token请求登录/注册接口即可。

2. AuthUserSerializer 缩进与Token创建逻辑错误

你写的get_auth_token方法缩进错误,被包含在Meta类内部无法生效;且直接调用Token.create会导致同一用户第二次登录时触发唯一键约束报错。同时序列化器字段配置缺失,无法返回你预期的is_superuser、auth_token字段。

修复方案:

class AuthUserSerializer(serializers.ModelSerializer):
    auth_token = serializers.SerializerMethodField()

    class Meta:
        model = User
        # 补充缺失的字段
        fields = ('id', 'email', 'username', 'first_name', 'last_name', 'is_active', 'is_staff', 'is_superuser', 'auth_token')
        read_only_fields = ('id', 'is_active', 'is_staff', 'is_superuser')
    
    # 移出Meta类,调整缩进,改用get_or_create避免重复创建报错
    def get_auth_token(self, obj):
        token, _ = Token.objects.get_or_create(user=obj)
        return token.key

3. 注册序列化器缺失username字段

你的注册请求要求传入username,但UserRegisterSerializer的fields配置中未包含该字段,导致创建用户时缺少必填参数报错。

修复方案:

class UserRegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        # 补充username字段
        fields = ('id', 'email', 'username', 'password', 'first_name', 'last_name')
    # 原有validate逻辑保持不变

4. 缺失依赖函数实现

代码中调用的get_and_authenticate_user、create_user_account两个函数没有导入也没有实现,会触发运行时错误。

修复方案:

在views.py中补充实现:

from rest_framework import serializers
from django.contrib.auth import authenticate

def get_and_authenticate_user(email, password):
    user = authenticate(username=email, password=password)
    if user is None:
        raise serializers.ValidationError("无效的邮箱或密码")
    if not user.is_active:
        raise serializers.ValidationError("用户已被禁用")
    return user

def create_user_account(email, password, username, first_name="", last_name=""):
    user = User.objects.create_user(
        email=email, username=username, password=password, 
        first_name=first_name, last_name=last_name
    )
    return user

5. 路由配置错误

logout接口的POST方法未绑定到对应的处理函数,会导致请求404。

修复方案:

urlpatterns = [
    url(r'^register/$', views.AuthViewSet.as_view({'post': 'register'}), name='register'),
    url(r'^login/$', views.AuthViewSet.as_view({'post': 'login'}), name='login'),
    # 修正logout的方法映射
    url(r'^logout/$', views.AuthViewSet.as_view({'post': 'logout'}), name='logout'),
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 07:39:02