如何修复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
相关产品推荐
相关产品推荐

