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

如何仅使用密码通过Simple JWT完成身份验证?

仅通过密码实现Simple JWT身份验证的解决方案

问题分析

你当前的代码存在两个核心问题:

  1. 父类TokenObtainPairSerializer默认要求username字段,仅设置username = serializers.SerializerMethodField(required=False)无法移除父类自带的必填username字段,因此系统仍会要求输入用户名。
  2. validate方法中的逻辑错误:你将credentials["password"]替换为user.username后调用父类验证,不符合父类验证逻辑,且父类依然需要username参数。

另外你的User模型继承AbstractBaseUser但未指定USERNAME_FIELD,这会导致Django用户认证系统报错,需要补充配置。

修正后的代码实现

1. 完善User模型

添加USERNAME_FIELD指定用password作为用户唯一标识:

from django.contrib.auth.models import AbstractBaseUser
from django.db import models
from django.core.validators import MinLengthValidator

SHIFTS = (
    # 你的班次选项
)
ROLES = (
    # 你的角色选项
)

class User(AbstractBaseUser):
    password = models.CharField('password', max_length=4, validators=[MinLengthValidator(4)], unique=True)
    name = models.CharField(max_length=50, blank=True)
    surname = models.CharField(max_length=100, blank=True)
    shift = models.CharField(max_length=50, choices=SHIFTS)
    role = models.CharField(max_length=50, choices=ROLES)
    work_start_time = models.DateTimeField()
    work_end_time = models.DateTimeField()

    # 指定password作为用户唯一标识字段
    USERNAME_FIELD = 'password'
    REQUIRED_FIELDS = []

2. 重写Token序列化器

完全自定义序列化逻辑,仅保留password字段,手动生成JWT Token:

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers
from .models import User

class CustomTokenPairSerializer(TokenObtainPairSerializer):
    # 仅定义password字段,移除父类的username字段
    password = serializers.CharField(write_only=True)

    def validate(self, data):
        password = data.get('password')
        
        if not password:
            raise serializers.ValidationError("密码不能为空")
        
        # 根据唯一密码查找用户
        user = User.objects.filter(password=password).first()
        if not user:
            raise serializers.ValidationError("用户不存在或密码错误")
        
        # 生成JWT Token
        refresh = self.get_token(user)
        return {
            'refresh': str(refresh),
            'access': str(refresh.access_token),
        }

3. 配置视图

修正类名拼写错误后保持视图配置:

from rest_framework_simplejwt.views import TokenObtainPairView
from .serializers import CustomTokenPairSerializer

class CustomObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenPairSerializer

安全建议

当前你的User模型中密码以明文存储,存在极大安全风险,建议改为Django默认的哈希存储方式:

  1. 修改模型中password字段定义:
password = models.CharField('password', max_length=128)
  1. 创建用户时使用set_password方法加密:
user = User.objects.create(...)
user.set_password("用户输入的密码")
user.save()
  1. 验证密码时使用check_password方法:
# 在序列化器的validate方法中
user = User.objects.filter(...)  # 需通过其他唯一标识(如工号)查找用户
if user and user.check_password(password):
    # 验证通过
else:
    raise serializers.ValidationError("密码错误")

内容的提问来源于stack exchange,提问作者Mike D Hovhannisyan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:55:38