2017-01-01 19 views
0

Когда пользователь меняет свой пароль, я хочу отправить сигнал, чтобы я мог делать некоторые вещи на некоторых моделях.Обнаружение измененного пароля в Django

Как создать этот сигнал?

Я смотрел на post_save сигнал для пользователя:

post_save.connect(user_updated, sender=User) 

Однако, как представляется, не будет ничего там для меня, чтобы проверить, если пароль был изменен:

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'} 

Я также вижу, что есть auth view password_change_done, но я не уверен, как бы я его использовал. https://docs.djangoproject.com/en/1.10/topics/auth/default/#built-in-auth-views

Любые идеи?

ответ

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 
+1

Обратите внимание, что это хорошо обнаруживает изменения в алгоритме соли или хеширования в качестве смены пароля. Если вам необходимо определить только фактические изменения пароля, вам нужно подключиться к представлению и проверить новый пароль до его хэширования. – knbk

+0

Когда соль или хеш-альг изменились? Сценарий обновления? – 43Tesseracts

+0

@ 43Tesseracts новые версии Django обновляют алгоритм/раунды паролей, и когда пользователи регистрируются, он обновляет пароль для использования более новой версии –

0

Если вы используете заказную модель пользователя, который предположительно может пересекать 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)