2

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

未找到具有给定凭据的活动帐户

DRF 身份验证失败

风景:

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

密码正在被散列。在这个阶段,进入管理页面并测试使用创建的帐户登录那里并得到

Django 管理问题

确保自定义用户模型具有 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... 创建用户,然后我可以登录管理面板并使用最初显示的令牌获取对视图验证该用户。

Django Admin 登录成功

simpleJWT 令牌

4

1 回答 1

3

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

如果您查看 Django 的set_password文档,您会发现它负责散列。

您正在做的是,首先您对密码进行哈希处理,并将其作为原始值提供给set_passwordvia 方法create_user。会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

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

于 2020-05-31T06:46:31.443 回答