简体   繁体   中英

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

When trying to authenticate a user created through a view in DRF Browsable API, I get

No active account found with the given credentials

DRF 身份验证失败

The view:

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)

The serializer:

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 . At this stage, went on to the admin page and tested to login there too with the created account and got

Django 管理问题

Made sure the custom user model had is_active, is_superuser and is_staff and checked if that would fix the issue but it didn't.

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

Then, tried to create the user using python manage.py createsuperuser ... doing so then I'm able to both login in the admin pannel and authenticate that user with the Token Obtain Pair view shown initially.

Django Admin 登录成功

simpleJWT 令牌

First of all. Thank you for providing all the details. It is always easier to debug. Coming to the issue, the problem is that you are using make_password explicitly.

If you would look through the Django's set_password documentation, you'd find that it takes care of hashing.

What you are doing is, first you are hashing your password, and providing it as a raw value to set_password method via create_user . The set_password would assume that as a raw value and would hash it again. Hence, your original password is not used at all.

You can just remove the use of make_password and instead change your serializer's create method to

class MyUserSerializer(serializers.ModelSerializer):

    ...

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

This should resolve your query. I hope it helps: :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM