Django REST Framework用户登录返回401问题:如何正确实现登录?
Django REST Framework登录返回401问题解决
问题核心
调用登录接口后返回401未授权状态码,authenticate方法返回None,无法验证用户身份。从打印结果和用户列表可确认用户已存在,但密码验证失败。
问题根源
问题出在用户注册逻辑,密码未被正确加密存储,导致authenticate无法匹配:
- 注册视图错误重写
get_queryset:CreateAPIView的get_queryset用于获取查询集,而非创建对象,原代码在该方法中调用create_user完全不符合DRF视图流程。 - 序列化器未处理密码加密:默认的
ModelSerializer.create会直接将密码明文存入数据库,而Django的authenticate需要验证加密后的密码,因此验证失败。
修正方案
1. 修复用户序列化器
重写序列化器的create方法,使用User.objects.create_user自动加密密码:
from rest_framework import serializers from django.contrib.auth.models import User class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ["username", "password"] # 按需选择字段,避免返回敏感信息 extra_kwargs = {"password": {"write_only": True}} def create(self, validated_data): user = User.objects.create_user(**validated_data) return user
2. 修复注册视图
使用CreateAPIView默认逻辑,无需重写get_queryset:
from django.contrib.auth.models import User from rest_framework import generics from ..serializers import UserSerializer class UserCreateApiView(generics.CreateAPIView): queryset = User.objects.all() serializer_class = UserSerializer
3. 验证修复效果
- 重新注册用户,检查数据库
auth_user表的password字段,应显示pbkdf2_sha256$开头的加密字符串,而非明文。 - 再次调用登录接口,
authenticate会正确返回用户对象,接口返回200状态码。
额外优化建议
- 登录接口可返回用户基本信息或认证Token(如JWT),方便前端后续请求身份验证。
- 用户列表接口简化写法,避免
queryset与序列化器冗余:
class UserListAPIView(generics.ListAPIView): queryset = User.objects.all() serializer_class = UserListSerializer class UserListSerializer(serializers.ModelSerializer): class Meta: model = User fields = ["id", "username", "last_login"]
内容的提问来源于stack exchange,提问作者Alex Ironside
相关产品推荐
相关产品推荐

