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

Django Rest Framework登录报错:Postman无法登录,提示invalid credentials

问题:注册正常但登录提示invalid credentials

我正在开发一款支持通过Postman注册、登录的Web应用,目前注册功能正常,但登录时提示invalid credentials,无法成功登录。以下是项目中的代码:

serializer.py

from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth import authenticate


class RegisterSerializer(serializers.Serializer):
    first_name = serializers.CharField()
    last_name = serializers.CharField()
    username = serializers.CharField()
    password = serializers.CharField()

    def validate(self, data):
        if User.objects.filter(username=data["username"]).exists():
            raise serializers.ValidationError("username is already taken")

        return data

    def create(self, validated_data):
        user = User.objects.create(first_name=validated_data["first_name"],
                                   last_name=validated_data["last_name"],
                                   username=validated_data["username"].lower()
                                   )
        user.set_password(validated_data["password"])

        return validated_data




class LoginSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    def validate(self, data):

        if not User.objects.filter(username=data["username"]).exists():
            raise serializers.ValidationError("account not found")

        return data

    def get_jwt_token(self, data):

        user = authenticate(username=data["username"], password=data["password"])

        if not user:
            return {"message": "invalid credentials", "data": {}}

        refresh = RefreshToken.for_user(user)

        return {
            "message": "login success",
            "data": {"token": {"refresh": str(refresh),
            "access": str(refresh.access_token)}}}

views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from .serializer import RegisterSerializer, LoginSerializer
from rest_framework import status


class RegisterView(APIView):
    def post(self, request):
        try:
            data = request.data

            serializer = RegisterSerializer(data=data)

            if not serializer.is_valid():
                return Response ({
                    "data" : serializer.errors,
                    "message" : "something went wrong",
                }, status=status.HTTP_400_BAD_REQUEST)

            serializer.save()

            return Response({
                "data" : {},
                "message" : "user created successfully",
                }, status=status.HTTP_201_CREATED)



        except Exception as e:
            print(e)
            return Response({
                "data" : {},
                "message" : "something went wrong",
            }, status=status.HTTP_400_BAD_REQUEST)


class LoginView(APIView):

    def post(self,request):
        try:
            data = request.data
            serializer = LoginSerializer(data=data)

            if not serializer.is_valid():
                return Response({
                "data": serializer.errors,
                "message": "something went wrong",
            }, status=status.HTTP_400_BAD_REQUEST)

            response = serializer.get_jwt_token(serializer.data)

            return Response(response, status=status.HTTP_200_OK)

        except Exception as e:
            print(e)
            return Response({
                "data" : {},
                "message" : "something went wrong",
            }, status=status.HTTP_400_BAD_REQUEST)

我已查阅JWT相关文档,仍未找到问题根源,希望能得到故障排查的帮助。


故障排查及修复方案

核心问题1:注册时未保存密码修改

在RegisterSerializer的create方法中,你通过User.objects.create()创建了用户并写入数据库,但之后调用user.set_password()修改了密码哈希,却没有执行user.save()将更新后的密码同步到数据库。这会导致数据库中存储的用户密码是无效的空白状态,最终authenticate验证失败,返回invalid credentials。

核心问题2(可选优化):用户名大小写不匹配

注册时你将用户名转为小写存储,但登录时直接使用用户输入的原始用户名进行验证。如果用户登录时输入大写字母,会出现“账号存在但验证失败”的矛盾情况(validate阶段能查到用户,但authenticate因为用户名大小写不匹配失败)。


修复代码

1. 修复RegisterSerializer的create方法

添加user.save()保存密码修改,同时建议返回用户对象(符合Serializer规范):

def create(self, validated_data):
    user = User.objects.create(
        first_name=validated_data["first_name"],
        last_name=validated_data["last_name"],
        username=validated_data["username"].lower()
    )
    user.set_password(validated_data["password"])
    user.save()  # 新增:保存更新后的密码到数据库
    return user  # 推荐返回user对象,而非validated_data

2. 修复LoginSerializer的用户名大小写问题

在get_jwt_token方法中将用户名转为小写,和注册逻辑保持一致:

def get_jwt_token(self, data):
    # 转为小写,匹配注册时的存储规则
    username = data["username"].lower()
    user = authenticate(username=username, password=data["password"])
    
    if not user:
        return {"message": "invalid credentials", "data": {}}

    refresh = RefreshToken.for_user(user)

    return {
        "message": "login success",
        "data": {
            "token": {
                "refresh": str(refresh),
                "access": str(refresh.access_token)
            }
        }
    }

验证步骤

  1. 重新注册一个新用户
  2. 使用该用户的用户名(大小写均可,若完成第二步修复)和密码登录,即可正常获取JWT Token。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:09:31