用户存在但无法使用 simpleJWT 和 Django Admin 进行身份验证

User exists but not able to authenticate using simpleJWT and Django Admin

尝试对通过 DRF Browsable API 中的视图创建的用户进行身份验证时,我得到

No active account found with the given credentials

观点:

class MyUserCreate(APIView):

    def post(self, request, format='json'):
        serializer = MyUserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

序列化器:

class MyUserSerializer(serializers.ModelSerializer):
    username = serializers.CharField(
            required=True,
            validators=[UniqueValidator(queryset=MyUser.objects.all())],
            min_length=5,
            max_length=20
            ),
    password = serializers.CharField(
            required=True,
            max_length=256
            )

    class Meta:
        model = MyUser
        fields = ('username', 'password')

    def create(self, validated_data):
        password = make_password(validated_data['password'])
        user = MyUser.objects.create_user(validated_data['username'], password)
        return user

The password is being hashed。在这个阶段,继续进入管理页面并测试使用创建的帐户登录那里并得到

确保自定义用户模型有 is_active、is_superuser 和 is_staff 并检查是否可以解决问题,但没有。

class MyUserManager(BaseUserManager):
    def create_user(self, username, password, **extra_fields):
        user = self.model(
            username=username
        )
        user.is_staff=True
        user.is_active=True
        user.is_superuser=True
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self.create_user(username, password, **extra_fields)    

class MyUser(AbstractBaseUser):
    objects = MyUserManager()
    class Meta:
        # managed = False
        db_table = 'user_entity'

    user_id = models.AutoField(primary_key=True, db_column='userId')
    username = models.CharField(db_column='username', unique=True, max_length=20)
    password = models.CharField(db_column='userPassword', max_length=256)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=True)
    is_superuser = models.BooleanField(default=True)

    USERNAME_FIELD = 'username'

    def __str__(self):
        return str(self.user_id) + " (%s)" % str(self.username)

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

然后,尝试使用 python manage.py createsuperuser 创建用户...这样我就可以登录管理面板并使用最初显示的令牌获取对视图验证该用户。

首先。感谢您提供所有详细信息。调试总是更容易。谈到这个问题,问题是您正在明确使用 make_password

如果您查看 Django 的 set_password 文档,您会发现它负责哈希处理。

您正在做的是,首先您对密码进行哈希处理,然后通过 create_user 将其作为原始值提供给 set_password 方法。 set_password 会将其假定为原始值并再次对其进行哈希处理。因此,您的原始密码根本没有被使用。

您可以只删除 make_password 的使用,而是将序列化程序的 create 方法更改为

class MyUserSerializer(serializers.ModelSerializer):

    ...

    def create(self, validated_data):
        user = MyUser.objects.create_user(validated_data['username'], validated_data["password"])
        return user

这应该可以解决您的查询。我希望它有所帮助! :)