Django rest auth user_logged_in 信号
Django rest auth user_logged_in signal
我有一个使用 django rest auth 的 django rest 应用程序。
每次用户使用信号登录时,我都会尝试记录一些内容。
我在网上搜索了如何使用信号,但没有找到任何有趣的 material 如何让它发挥作用。我认为问题可能出在 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'
由于某些奇怪的原因,这在 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))
配置基于令牌的身份验证时,Django Rest Framework 似乎没有发出 user_logged_in
信号:https://github.com/encode/django-rest-framework/issues/3869
这是我使用 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)
对于未来的谷歌员工。 OP 最初的问题是他想在用户每次使用 rest_auth 登录时记录一些东西。您可能希望 rest_auth 发出这样的信号,但 rest_auth 根据登录类型做不同的事情。对于会话登录,rest_auth 调用 django 的正常登录例程并且确实发出信号。但是对于基于令牌的身份验证,rest_auth 创建令牌并 returns 它并且没有调用 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
由于某些奇怪的原因,它没有从 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
我有一个使用 django rest auth 的 django rest 应用程序。 每次用户使用信号登录时,我都会尝试记录一些内容。
我在网上搜索了如何使用信号,但没有找到任何有趣的 material 如何让它发挥作用。我认为问题可能出在 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'
由于某些奇怪的原因,这在 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))
配置基于令牌的身份验证时,Django Rest Framework 似乎没有发出 user_logged_in
信号:https://github.com/encode/django-rest-framework/issues/3869
这是我使用 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)
对于未来的谷歌员工。 OP 最初的问题是他想在用户每次使用 rest_auth 登录时记录一些东西。您可能希望 rest_auth 发出这样的信号,但 rest_auth 根据登录类型做不同的事情。对于会话登录,rest_auth 调用 django 的正常登录例程并且确实发出信号。但是对于基于令牌的身份验证,rest_auth 创建令牌并 returns 它并且没有调用 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
由于某些奇怪的原因,它没有从 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