user_login_failed 信号的 Django 日志用户 IP
Django log user IP for user_login_failed signal
我想在我的 Django 应用程序中记录用户 IP 地址,专门用于登录、注销和登录失败事件。我正在使用 Django 内置函数,如下所示:
from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed
from ipware.ip import get_ip
import logging
logger = logging.getLogger(__name__)
def log_logged_in(sender, user, request, **kwargs):
logger.info("%s User %s successfully logged in" % (get_ip(request), user))
def log_logged_out(sender, user, request, **kwargs):
logger.info("%s User %s successfully logged out" % (get_ip(request), user))
def log_login_failed(sender, credentials, **kwargs):
logger.warning("%s Authentication failure for user %s" % ("...IP...", credentials['username']))
user_logged_in.connect(log_logged_in)
user_logged_out.connect(log_logged_out)
user_login_failed.connect(log_login_failed)
问题是我还没有找到获取 user_login_failed
信号 IP 的方法,因为此函数的参数中没有 request
(https://docs.djangoproject.com/en/1.7/ref/contrib/auth/#module-django.contrib.auth.signals) . credentials
参数是一个字典,只包含 username
和 password
字段。
如何获取此信号的 IP 地址?
非常感谢您的帮助。
不幸的是user_login_failed
信号没有将请求作为参数传递。
结账 django-axes
— https://github.com/django-pci/django-axes/
它使用自定义视图装饰器来跟踪失败的登录。
https://github.com/django-pci/django-axes/blob/master/axes/decorators.py#L273
您可以覆盖登录表单并在那里拦截它。
它在那个阶段有要求。
import logging
from django.contrib.admin.forms import AdminAuthenticationForm
from django import forms
log = logging.getLogger(__name__)
class AuthenticationForm(AdminAuthenticationForm):
def clean(self):
# to cover more complex cases:
#
ip = request.META.get('REMOTE_ADDR')
try:
data = super(AuthenticationForm, self).clean()
except forms.ValidationError:
log.info('Login Failed (%s) from (%s)', self.cleaned_data.get('username'), ip)
raise
if bool(self.user_cache):
log.info('Login Success (%s) from (%s)', self.cleaned_data.get('username'), ip)
else:
log.info('Login Failed (%s) from (%s)', self.cleaned_data.get('username'), ip)
return data
要将其安装到站点,您需要将其附加到 django.contrib.admin.site.login_form
我建议在您应用的 ready() 方法中这样做:
from django.contrib.admin import site as admin_site
class Config(AppConfig):
...
def ready(self):
# Attach the logging hook to the login form
from .forms import AuthenticationForm
admin_site.login_form = AuthenticationForm
我刚刚在较新的 Django 版本(我使用的是 2.1)中发现更新了它,现在它在 user_login_failed 信号中包含了请求对象:
我想在我的 Django 应用程序中记录用户 IP 地址,专门用于登录、注销和登录失败事件。我正在使用 Django 内置函数,如下所示:
from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed
from ipware.ip import get_ip
import logging
logger = logging.getLogger(__name__)
def log_logged_in(sender, user, request, **kwargs):
logger.info("%s User %s successfully logged in" % (get_ip(request), user))
def log_logged_out(sender, user, request, **kwargs):
logger.info("%s User %s successfully logged out" % (get_ip(request), user))
def log_login_failed(sender, credentials, **kwargs):
logger.warning("%s Authentication failure for user %s" % ("...IP...", credentials['username']))
user_logged_in.connect(log_logged_in)
user_logged_out.connect(log_logged_out)
user_login_failed.connect(log_login_failed)
问题是我还没有找到获取 user_login_failed
信号 IP 的方法,因为此函数的参数中没有 request
(https://docs.djangoproject.com/en/1.7/ref/contrib/auth/#module-django.contrib.auth.signals) . credentials
参数是一个字典,只包含 username
和 password
字段。
如何获取此信号的 IP 地址?
非常感谢您的帮助。
不幸的是user_login_failed
信号没有将请求作为参数传递。
结账 django-axes
— https://github.com/django-pci/django-axes/
它使用自定义视图装饰器来跟踪失败的登录。
https://github.com/django-pci/django-axes/blob/master/axes/decorators.py#L273
您可以覆盖登录表单并在那里拦截它。 它在那个阶段有要求。
import logging
from django.contrib.admin.forms import AdminAuthenticationForm
from django import forms
log = logging.getLogger(__name__)
class AuthenticationForm(AdminAuthenticationForm):
def clean(self):
# to cover more complex cases:
#
ip = request.META.get('REMOTE_ADDR')
try:
data = super(AuthenticationForm, self).clean()
except forms.ValidationError:
log.info('Login Failed (%s) from (%s)', self.cleaned_data.get('username'), ip)
raise
if bool(self.user_cache):
log.info('Login Success (%s) from (%s)', self.cleaned_data.get('username'), ip)
else:
log.info('Login Failed (%s) from (%s)', self.cleaned_data.get('username'), ip)
return data
要将其安装到站点,您需要将其附加到 django.contrib.admin.site.login_form
我建议在您应用的 ready() 方法中这样做:
from django.contrib.admin import site as admin_site
class Config(AppConfig):
...
def ready(self):
# Attach the logging hook to the login form
from .forms import AuthenticationForm
admin_site.login_form = AuthenticationForm
我刚刚在较新的 Django 版本(我使用的是 2.1)中发现更新了它,现在它在 user_login_failed 信号中包含了请求对象: