【问题标题】:Django rest auth user_logged_in signalDjango rest auth user_logged_in 信号
【发布时间】:2017-09-04 03:32:43
【问题描述】:

我有一个使用 django rest auth 的 django rest 应用程序。 每次用户使用信号登录时,我都会尝试记录一些内容。

我在网上搜索了如何使用信号,但没有找到任何有趣的材料来说明如何使其工作。我认为问题可能出在 allauth 信号上。下面的配置有问题吗?

signals.py

import logging

from allauth.account.signals import user_logged_in
from django.dispatch import receiver

logger = logging.getLogger(__name__)


@receiver(user_logged_in)
def login_logger(request, user, **kwargs):
    logger.info("{} logged in with {}".format(user.email, request))

apps.py

from django.apps import AppConfig


class UsersConfig(AppConfig):
    name = 'users'

    def ready(self):
        import users.signals

__init__.py

default_app_config = 'users.apps.UsersConfig'

【问题讨论】:

    标签: python django rest django-allauth django-signals


    【解决方案1】:

    由于某种奇怪的原因,它没有从signals.py 接收。但是,您仍然可以使用以下方法保持关注点分离。这对我有用,同时仍然使信号逻辑远离我的模型。

    signals.py

    import logging
    
    from allauth.account.signals import user_logged_in
    from django.dispatch import receiver
    
    logger = logging.getLogger(__name__)
    
    
    @receiver(user_logged_in)
    def login_logger(request, user, **kwargs):
        logger.info("{} logged in with {}".format(user.email, request))
    

    models.py

    from .signals import *
    
    // Your models here
    
    class Foo(models.Model):
        pass
    

    【讨论】:

    • 自从更新到 dajngo 3.2 后,这个回归问题已经解决了。现在,将这些函数放入 signal.py 时,它也可以正常工作。
    【解决方案2】:

    对于未来的谷歌人。 OP 最初的问题是,他想在每次用户使用 rest_auth 登录时记录一些东西。你会期望 rest_auth 发出这样的信号,但是 rest_auth 会根据登录的类型做不同的事情。对于会话登录,rest_auth 调用 django 的正常登录例程,并发出一个信号。但是对于基于令牌的身份验证,rest_auth 会创建令牌并返回它,并且不会调用 django,也不会发出任何信号。 这是rest_auth login code

    要获得您想要的行为,您必须覆盖 rest_auth 的 default token handler(这很简单),以便您知道何时创建令牌,然后根据需要记录事件。

    在django的settings.py文件中添加:

    REST_AUTH_TOKEN_CREATOR = '<your_dotted_project_path>.create_login_token'

    在您项目的某个文件中:

    # this is the same as the default rest_auth token handler except we
    # don't throw away the 'created' part because we care whether it was
    # created or just retrieved.
    def create_login_token(token_model, user, serializer):
        token, created = token_model.objects.get_or_create(user=user)
        if created:
            >>> log it or emit your own signal or whatever <<<
    
        return token
    

    【讨论】:

      【解决方案3】:

      这是我使用djangorestframework-jwt==1.11.0 解决它的方法:

      settings.py

      from django.contrib.auth.signals import user_logged_in
      
      def jwt_response_payload_handler(token, user=None, request=None):
          if user and request:
              user_logged_in.send(sender=user.__class__, request=request, user=user)
          return {
              'token': token,
          }
      
      JWT_AUTH = {
          'JWT_RESPONSE_PAYLOAD_HANDLER': jwt_response_payload_handler,
      }
      

      models.py

      from django.contrib.auth.signals import user_logged_in
      
      def login_handler(sender, user, request, **kwargs):
          print('logged in')
      
      user_logged_in.connect(login_handler)
      

      【讨论】:

      • 它也对我有用。谢谢。但是,最好还提到 'rest_framework_jwt.authentication.JSONWebTokenAuthentication' 需要添加到 settings.py 中的 REST_FRAMEWORK 变量中
      【解决方案4】:

      配置基于令牌的身份验证时,Django Rest Framework 似乎没有发出user_logged_in 信号:https://github.com/encode/django-rest-framework/issues/3869

      【讨论】:

        【解决方案5】:

        由于某种奇怪的原因,这在放在signals.py 时似乎不起作用,signals.py 的这个实现对项目的每个部分都很好,除了allauth(我也有我的个人经验)。检查这个 github 问题 https://github.com/pennersr/django-allauth/issues/347

        出于某种奇怪的原因,将此代码 (signals.py) 移至同一应用程序的 models.py 将起作用。

        # place this in models.py
        from allauth.account.signals import user_logged_in
        from django.dispatch import receiver
        
        logger = logging.getLogger(__name__)
        
        
        @receiver(user_logged_in)
        def login_logger(request, user, **kwargs):
            logger.info("{} logged in with {}".format(user.email, request))
        

        【讨论】:

        • 我是否遗漏了一些配置内容?
        • 对我来说一切都很好,你能确保 users 应用程序的记录器在设置中配置(只是为了确保),否则我看不出它不应该工作的任何原因
        • 把它放在models.py,然后重启本地服务器,它应该可以工作了
        • 我已经尝试将代码移动到model.py,但它不起作用。我认为问题可能出在 allauth 配置中,因为我尝试调试它并且它从未命中任何接收器......然后我尝试添加 request_finished 接收器并且它起作用了。所以我认为问题出在 allaurh 信号上,但是文档太差了。
        • 自从更新到 dajngo 3.2 后,这个回归问题已经解决了。现在,将这些函数放入 signal.py 时,它也可以正常工作。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-31
        • 1970-01-01
        • 2020-10-03
        • 1970-01-01
        • 2019-06-26
        • 1970-01-01
        • 2017-12-02
        相关资源
        最近更新 更多