DRF JWT认证下request.user返回AnonymousUser的解决方法
解决方法
1. 修正视图装饰器顺序
DRF函数视图的装饰器执行顺序是自下而上,必须把@api_view放在最外层(最上方),否则权限与认证逻辑无法正确触发。修改后的视图代码:
@api_view(["POST"]) @permission_classes([IsAuthenticated]) def createAppoinment(req): data = req.data serializer = AppoinmentSerializer(data=req.data) if serializer.is_valid(): serializer.save(owner=req.user) return Response(status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
(注:补充返回serializer.errors方便调试参数问题)
2. 验证前端请求头格式
确保前端发送POST请求时,Authorization请求头严格遵循格式:
Bearer <你的JWT Token>
注意Bearer与Token之间必须有一个空格,且拼写与SIMPLE_JWT配置的AUTH_HEADER_TYPES一致(此处为大写Bearer)。
3. 检查自定义用户模型配置
确认NewUser模型正确继承必要基类并配置核心字段,示例模板:
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin from django.db import models class NewUserManager(BaseUserManager): def create_user(self, email, password=None, **extra_fields): if not email: raise ValueError('必须填写邮箱字段') email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, password=None, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) return self.create_user(email, password, **extra_fields) class NewUser(AbstractBaseUser, PermissionsMixin): email = models.EmailField(unique=True) username = models.CharField(max_length=100, unique=True) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) USERNAME_FIELD = 'email' # 指定登录标识字段 REQUIRED_FIELDS = ['username'] objects = NewUserManager()
如果自定义用户模型的主键不是默认的id,需要在SIMPLE_JWT配置中补充指定:
SIMPLE_JWT = { "AUTH_HEADER_TYPES": ("Bearer",), "USER_ID_FIELD": "你的主键字段名", # 例如用username作为主键则写"username" }
4. 确认DRF全局认证配置生效
检查settings.py中REST_FRAMEWORK的认证配置,避免与Session认证冲突(前后端分离场景建议仅保留JWT认证):
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ), }
5. 调试认证过程
若以上步骤仍未解决问题,可在视图中添加调试代码排查:
@api_view(["POST"]) @permission_classes([IsAuthenticated]) def createAppoinment(req): print("当前认证用户:", req.user) print("认证令牌信息:", req.auth) print("请求头Authorization:", req.headers.get('Authorization')) # 后续业务代码...
通过控制台输出确认Token是否正确携带、认证逻辑是否成功解析用户。
内容的提问来源于stack exchange,提问作者Muhammed Rinshid
相关产品推荐
相关产品推荐

