2017-01-01 70 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'} 

我也看到有一個password_change_done身份驗證視圖,但我不知道如何使用它。 https://docs.djangoproject.com/en/1.10/topics/auth/default/#built-in-auth-views

任何想法?

回答

5

您可以使用pre_save信號。 kwargs['instance']將包含 更新的密碼,您可以如果您正在使用自定義的用戶模型,你大概可以相交set_password()呼叫設置一個標誌的實例與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

什麼時候salt或hash alg會改變?升級場景? – 43Tesseracts

+0

@ 43Tesseracts更新版本的Django更新所使用的密碼算法/輪次,並且當用戶登錄時更新密碼以使用更新版本 –

0

得到原來的密碼,然後挑選在一個信號內存在它的存在:

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)