gpt4 book ai didi

Django 用户模型 : what is the purpose of password changes in the save() method

转载 作者:行者123 更新时间:2023-12-04 14:17:58 24 4
gpt4 key购买 nike

有时我想以编程方式设置密码。我执行以下操作:

https://docs.djangoproject.com/en/2.2/topics/auth/default/#changing-passwords
You can also change a password programmatically, using set_password():

from django.contrib.auth.models import User
u = User.objects.get(username='john')
u.set_password('new pass')
u.save()

我想看看当我们运行 u.save() 时,save() 是如何实现的

基本上我想了解 AbstractBaseUser 中使用的 save() 方法

# ./.venv/lib/python3.7/site-packages/django/contrib/auth/base_user.py
class AbstractBaseUser(models.Model):
password = models.CharField(_('password'), max_length=128)

........

# Stores the raw password if set_password() is called so that it can
# be passed to password_changed() after the model is saved.
_password = None


def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if self._password is not None:
password_validation.password_changed(self._password, self)
self._password = None

........

def set_password(self, raw_password):
self.password = make_password(raw_password)
self._password = raw_password

这里是 def save(self, *args, **kwargs):

super().save(*args, **kwargs)

将在验证密码的下一行 password_validation.password_changed 之前保存由 set_password 设置的密码

那么先保存密码然后再验证有什么意义呢,因为它已经进入了数据库。

最佳答案

password_validation.password_changed 并不像您想象的那样。

实际的密码验证是在保存用户对象之前通过调用 django.contrib.auth.password_validation.validate_password 方法完成的。此方法调用您设置中的每个验证器 AUTH_PASSWORD_VALIDATORS,并在这些验证器中的任何一个失败时引发异常。这可以是任何类型的验证,例如新密码是否足够复杂,或者它与用户名是否足够不同。

根据 the docs :

By default, validators are used in the forms to reset or change passwords and in the createsuperuser and changepassword management commands.

Validators aren’t applied at the model level, for example in User.objects.create_user() and create_superuser(), because we assume that developers, not users, interact with Django at that level and also because model validation doesn’t automatically run as part of creating models.

因此,用户保存模型不会对用户密码进行任何验证,而表单和命令会。如果您在代码中的某处手动设置密码,请确保您自己进行验证。

那么 password_validation.password_changed(self._password, self) 做了什么?

简单地说,它通知所有活跃的验证者用户已经更改了他们的密码,以及实际的原始新密码。为什么这是必要的?假设我编写了一个验证器来检查用户是否试图将他们的密码更改为他们以前使用过的密码。这个验证器需要知道用户过去使用过哪些密码,所以我需要为每个用户保存一个(散列的)原始密码列表。

password_changed 基本上是 Django 对所有密码验证器说的一种方式:“嘿,请注意,用户的密码已更改为此值,因此如果您需要跟踪出于某种原因,现在就做吧,因为在此之后,我将销毁此密码的未哈希版本”

关于Django 用户模型 : what is the purpose of password changes in the save() method,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58265752/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com