在Django中检测更改的密码

43T*_*cts 3 python django django-signals django-authentication

当用户更改密码时,我想发送一个信号,以便我可以在某些型号上做一些事情.

我该如何创建此信号?

我查看post_save了用户的信号:

post_save.connect(user_updated, sender=User)
Run Code Online (Sandbox Code Playgroud)

但是,我似乎没有任何东西可以检查密码是否已更改:

def user_updated(sender, **kwargs):
    print(kwargs) # {'created': False, 'raw': False, 'instance': <User: 100002>, 'update_fields': None, 'signal': <django.db.models.signals.ModelSignal object at 0x7ff8862f03c8>, 'using': 'default'}
Run Code Online (Sandbox Code Playgroud)

我也看到有一个password_change_doneauth视图,但我不确定我是如何使用它的.https://docs.djangoproject.com/en/1.10/topics/auth/default/#built-in-auth-views

有任何想法吗?

Ian*_*ark 6

如果您使用的是自定义用户模型,您可能可以交叉调用set_password()以在实例上设置标志,然后在信号中获取其存在:

from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.db.models.signals import post_save


class User(AbstractBaseUser, PermissionsMixin):
    def set_password(self, password):
        super(User, self).set_password(password)
        self._set_password = True

    @classmethod
    def user_saved(cls, sender, instance, **kwargs):
        if getattr(instance, '_set_password', False):
            # Take action


post_save.connect(User.user_saved, sender=User)
Run Code Online (Sandbox Code Playgroud)


Mes*_*ahi 5

您可以使用pre_save信号.kwargs['instance']将包含更新的密码,您可以使用旧密码User.objects.get(id= user.id).password

@receiver(pre_save, sender=User)
def user_updated(sender, **kwargs):
    user = kwargs.get('instance', None)
    if user:
        new_password = user.password
        try:
            old_password = User.objects.get(pk=user.pk).password
        except User.DoesNotExist:
            old_password = None
        if new_password != old_password:
        # do what you need here
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这很好地将盐或散列算法中的更改检测为密码更改。如果您只需要检测实际的密码更改,则需要在对新密码进行散列处理之前钩入视图并检查新密码。 (2认同)