Django по-разному хэширует мои пароли при создании пользователя и при попытке аутентификации пользователя
У меня проблемы с аутентификацией, и я обнаружил, что проблема в том, что когда я создаю пользователя, его пароль хэшируется не в PBKDF2, а в другом стиле. Вместо этого пароли всегда имеют такой формат: !iak7ijJTzsXRgsbwqtQBtXCZeU3Ccd96k2PpOCRa .
Однако, когда я работаю в моих представлениях make_password и check_password используются PBKDF2.
Модель:
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
Я подозреваю, что проблема исходит от моей пользовательской модели, но она идентична той, которую я написал для другого приложения, в котором не было никаких проблем.
Зарегистрируйте представление: 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)
Вид входа:
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:
! в начале значения пароля имеет особое значение в Django - это означает, что для пользователя был установлен непригодный пароль - остальное значение является случайной строкой, которая никогда не будет успешно проверена.
Итак, вопрос в том, почему задается непригодный пароль? Из вашего кода я вижу две возможности:
UserManager.create_super_userвообще не устанавливает пароль пользователя - если вы используете это для создания пользователей, то пароль для них не будет установлен.Если вы используете
CreateUserSerializer, то может оказаться, что значениеpasswordравноNone- нам нужно посмотреть определение сериализатора, чтобы подтвердить, будет ли нулевое значение считаться допустимым. Я думаю, что это наиболее вероятная проблема. ПередачаNoneвcreate_userприведет к тому, чтоset_passwordустановит непригодный пароль. Затем необходимо выяснить, почему в сериализатор передается пустое значение.
Проблема заключалась в том, что solarissmoke предложил с CreateUserSerializer. У меня пароль был установлен только на запись, что не позволяло моему представлению добраться до пароля, вместо этого оно возвращало None.
Я изменил свою точку зрения следующим образом:
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'password')
extra_kwargs = {
'password' : {'write_only': True}
}
К этому (исправленная версия):
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'password')