djangoauthenticationdjango-rest-frameworkrequestsuperuser

Can not login as superuser in DRF


Created superuser several times with this credentials.
username: admin
password: root
Did it with terminal and with Djnago ORM. Same result.

>>> from bank.models import User
>>> User.objects.create_superuser(username="admin", password="root")
>>> from django.contrib.auth import authenticate
>>> u = authenticate(username="admin", password="root")
>>> u
>>> type(u)
<class 'NoneType'>

>>> admin = User.objects.get(username="admin")
>>> admin
<User: admin>
>>> admin.is_active
True
>>> admin.is_staff
True
>>> admin.is_superuser
True

It's started since I started using python-jwt tokens, but it fails before code goes to token part.
Same login function as normal user works as it supposed to be and gives working token.

@api_view(['POST'])
def login_view(request):
    username = request.data.get("username")
    password = request.data.get("password")
    user = User.objects.filter(username=username).first()

    if user is None:
        raise exceptions.AuthenticationFailed("Invalid Credentials")
    if not user.check_password(password):
        # code fails here after trying lo log in as superuser
        raise exceptions.AuthenticationFailed("Invalid Credentials")

    token = services.create_token(user_id=user.id)
    resp = response.Response()
    resp.set_cookie(key="jwt", value=token, httponly=True)
    resp.data = {"token": token}
    return resp

Solution

  • It happens because of UserManager. Default Django UserManager hashes password when creates superuser. When you try to create normal user, by default its password doesn't get hashed. In my case I hashed password by rewriting save() method in User model.

        def save(self, *args, **kwargs):
            self.set_password(self.password)
            super().save(*args, **kwargs)
    

    And it works perfectly for normal user, but superuser's password hashes by itself, so because of this method it hashes twice. So password check looked something like \

    hash(input_password) == hash(hash(original_password))
    

    That's why I could not login as superuser.

    UPD: just create user with User.objects.create_user(**data). It hashes password automatically. In that case you do not even need to rewrite save() method in User model.