Django 在创建用户时对我的密码进行哈希处理与尝试对用户进行身份验证时不同
Django is hashing my passwords different when creating a User vs trying to authenticate a user
我在进行身份验证时遇到问题,我发现问题出在我创建用户时,他们的密码散列方式与 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中有特殊含义——表示已经为用户设置了一个unusable password——其余的值只是一个随机值永远不会成功验证的字符串。
所以问题是为什么设置了一个不可用的密码?我可以从您的代码中看到两种可能性:
UserManager.create_super_user
根本不设置用户密码 - 如果您使用它来创建用户,则不会为他们设置密码。
如果您使用的是 CreateUserSerializer
,那么 password
的值可能是 None
- 我们需要查看序列化器定义确认 null 值是否被视为有效。我认为这是最有可能的问题。将 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')
我在进行身份验证时遇到问题,我发现问题出在我创建用户时,他们的密码散列方式与 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中有特殊含义——表示已经为用户设置了一个unusable password——其余的值只是一个随机值永远不会成功验证的字符串。
所以问题是为什么设置了一个不可用的密码?我可以从您的代码中看到两种可能性:
UserManager.create_super_user
根本不设置用户密码 - 如果您使用它来创建用户,则不会为他们设置密码。如果您使用的是
CreateUserSerializer
,那么password
的值可能是None
- 我们需要查看序列化器定义确认 null 值是否被视为有效。我认为这是最有可能的问题。将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')