我正在开发一个旧的/过时的Webapp,并将其带入2018年的世界。
该应用程序在Django 1.4.19和Python 2上运行,计划将两者升级到最新的LTS版本。
但是,在此升级开始之前,我们必须满足一些GDPR /许可要求。
用户当前可以使用密码和4位PIN码登录到我们的应用程序。 PIN码是在UserProfile
型号上设置的,就像这样:
class UserProfile(models.Model):
DEFAULT_PINCODE = '0000'
PIN_VALIDATOR = RegexValidator(
regex='^\d{4}$', message=_('Error message.'),
code='invalid_pin')
MAX_LOGIN_ATTEMPTS = 4
LOGIN_BLOCK_DURATION = timedelta(hours=1)
user = models.OneToOneField(User, related_name='profile')
pincode = models.CharField(
_('pin'), max_length=1000, null=True,
blank=True, default=DEFAULT_PINCODE,
validators=[PIN_VALIDATOR])
此文件存储为纯文本格式,我们希望对其进行哈希/盐化处理,并将其保存在数据库中。
为此,我创建了以下方法。
def check_pin(self, raw_pincode):
"""
:param raw_password:
:return: a boolean that indicates whether the raw_pincode matches
self.pincode
"""
return check_password(raw_pincode, self.pincode)
def save(self, *args, **kwargs):
self.pincode = make_password(self.pincode)
super(UserProfile, self).save(*args, **kwargs)
后一种方法可确保对密码进行加密。此方法要求我将pincode
字段从IntegerField
更改为CharField
,并返回一个较大的加密字符串,但是它可以工作-当我在admin中键入值并保存时,我得到一个像pbkdf2_sha256$10000$MXyCQoqecmFt$kWEOpO8/GUk76ubB5wsR7Ry1v5WR30RMDQpytPTuyPY=
但是,第一种方法给我带来麻烦。
在我们的PinLoginForm
上(在'def clean
方法下),我运行以下代码来验证该引脚
try:
data['pin'] = pin
print(self.user_profile.check_pin(pin))
print(pin)
print(self.user_profile.pincode)
if self.user_profile.check_pin(pin) == False:
raise KeyError
except KeyError:
raise forms.ValidationError(_('Wrong pincode.'))
这是很奇怪的事情,此代码仅在第一次使用时有效(直接在admin中设置了密码之后) 打印语句返回
True
4444
pbkdf2_sha256$10000$NOMCsVFJHj3j$72dHZMVEuD6vGsjhPSw5cNY6eefRTwI1yfXrwUOkd/Q=
但是,当我注销并重试时,它表明我的密码不正确,并且打印语句提供了以下输出:
False
4444
pbkdf2_sha256$10000$wkGSA5kHnJPg$fO8BGkFe787ufKUoKMgwcBqg0VxBACf4FxT9lkwzTyU=
几乎就像引脚已更改一样,但我没有更改。有很多软件包可以解决我的问题,但是它们要么在Django 1.4上不起作用(我们必须先部署它,然后才能继续升级)或python 3(这将是我们的下一个升级),因此“手动的方法。
有人知道我在做什么错吗?