I'm having trouble getting authentication to work and I found that the problem is my when I create a user their password is hashed in a different style than PBKDF2. Instead the passwords are always in a format like this: !iak7ijJTzsXRgsbwqtQBtXCZeU3Ccd96k2PpOCRa .
However, when I'm working in my views make_password
and check_password
are using PBKDF2.
Model:
class UserManager(BaseUserManager):
def create_user(self, email, password):
if not email:
raise ValueError("User must have an email address")
user = self.model(
email = self.normalize_email(email),
)
user.set_password(password)
user.save()
return user
def create_super_user(self, email, password=None):
if not email:
raise ValueError("User must have an email address")
user = self.model(
email = self.normalize_email(email),
)
user.is_admin = True
user.save()
return user
class User(AbstractBaseUser):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
email=models.EmailField(
verbose_name='Email',
max_length=255,
unique=True
)
password=models.CharField(
max_length=255,
verbose_name='password'
)
username = None
first_name = None
last_name = None
is_active = models.BooleanField(default=True)
EMAIL_FIELD = 'email'
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return self.email
I suspect the issue is coming from my custom Model, but it's identical to one I wrote for another app that had no issues.
Register View:
class CreateUser(APIView):
serializer_class = CreateUserSerializer
def post(self, request, format='json'):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
email = serializer.data.get('email')
password = serializer.data.get('password')
userObj = User.objects.create_user(email=email, password=password)
userObj.save()
return Response(status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Login View:
class LogIn(APIView):
serializer_class = LogInSerializer
authentication_classes = [SessionAuthentication, BasicAuthentication]
def post(self, request, format='json'):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
email = serializer.data.get('email')
password = serializer.data.get('password')
tObj = User.objects.get(email=email)
hashed_pwd = make_password("123456")
print(hashed_pwd)
print(tObj.password)
print(tObj.check_password(password))
user = authenticate(email=email, password=password)
print(user)
if user is not None:
CodePudding user response:
The !
at the start of the password value has a special meaning in Django - it means that an unusable password has been set for the user - the rest of the value is just a random string that will never be successfully validated.
So the question is why is an unusable password being set? There are two possibilities I can see from your code:
UserManager.create_super_user
doesn't set the user's password at all - if you are using this to create users, then no password will be set for them.If you're using the
CreateUserSerializer
, then it may be that the value ofpassword
isNone
- we would need to see the serializer definition to confirm whether a null value would be considered valid. I think this is the most likely issue. PassingNone
tocreate_user
will causeset_password
to set an unusable password. You then need to investigate why an empty value is being passed to the serializer.
CodePudding user response:
The problem was what solarissmoke proposed with the CreateUserSerializer. I had my password set to write only which wasn't letting my view to get to password, instead it was returning None.
I changed my view from this:
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'password')
extra_kwargs = {
'password' : {'write_only': True}
}
To this (corrected version):
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'password')