Пользователь существует, но не может пройти аутентификацию с помощью simpleJWT и Django Admin.

При попытке аутентифицировать пользователя, созданного с помощью представления в 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

Затем я попытался создать пользователя с помощью _4 _..., сделав это, тогда я могу как войти в систему в панели администратора, так и аутентифицировать этого пользователя с помощью представления Token Obtain Pair, показанного изначально.

Успешный вход в систему администратора Django

токен simpleJWT


person Tiago Martins Peres 李大仁    schedule 30.05.2020    source источник
comment
После того, как вы создали суперпользователя через терминал, вы проверяли, создаются ли пользователи или нет? Так же должны быть записи пользователей.   -  person gutsytechster    schedule 31.05.2020
comment
Да офс. Я их все вижу в БД @gutsytechster   -  person Tiago Martins Peres 李大仁    schedule 31.05.2020
comment
Понятно, значит, проблема в пароле. Можете ли вы проверить мой ответ ниже, если он работает?   -  person gutsytechster    schedule 31.05.2020


Ответы (1)


Прежде всего. Спасибо, что предоставили все подробности. Отлаживать всегда проще. Что касается проблемы, проблема в том, что вы явно используете make_password.

Если вы посмотрите set_password, вы обнаружите, что он позаботится о хешировании.

Что вы делаете, это сначала хешируете свой пароль и предоставляете его как необработанное значение методу set_password через 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

Это должно решить ваш вопрос. Я надеюсь, что это помогает! :)

person gutsytechster    schedule 31.05.2020