Py学习  »  Django

是否可以将登录尝试的所有输入存储在django文件中?

Adam • 3 年前 • 1688 次点击  

我想在Django中记录所有用户登录和注销尝试。此记录应显示所有登录/注销用户的历史记录、IP地址和登录/注销时间。

这个 django_admin_log 表似乎只记录其他模型的添加/删除/更改活动,而不是用户访问历史。我也已经查过了 user_logged_in , user_logged_out 信号。似乎如果我要使用这些信号,我需要创建一个新表来记录所有用户登录/注销的历史记录。Django中有内置的方法来实现这一点吗?还是有现成的套餐?我检查过其他软件包,那些与登录尝试相关的软件包只限制失败的尝试,但不记录成功的登录/注销。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/130015
文章 [ 2 ]  |  最新文章 3 年前
Benyamin Jafari
Reply   •   1 楼
Benyamin Jafari    3 年前

这里有一个与Django用户集成的新答案( AbstractUser )详情如下:

模型py (创建从Django用户继承的模型):

from django.contrib.auth.models import AbstractUser
from django.db import models

class UserModel(AbstractUser):  # Inherit from django user
    last_logout = models.DateTimeField(null=True, blank=True)
    status = models.CharField(max_length=64)
    ip = models.GenericIPAddressField(null=True)

    def __str__(self):
        return '{} - {}'.format(self.username, self.ip)

信号py (记录到Django模型和日志):

from django.contrib.auth.signals import user_logged_out
from django.dispatch import receiver
from django.utils import timezone
from <model> import UserModel  # above model
from logging import getLogger

logger = getLogger(__name__)
  
def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip


@receiver(user_logged_out)
def user_logged_out_callback(sender, request, user, **kwargs):
    ip = get_client_ip(request)
    username = request.user.username  # get the username.
    now = timezone.now()
    logger.warn('{} logged out with {} IP'.format(user, ip))  # recording to log
    UserModel.objects.filter(username=username).update(last_logout=now,
                                                   status='user_logged_out',
                                                   ip=ip
                                                   )  # recording to the model
        

[ 笔记 ]:

  • username 位于 AbstarctUser 领域。

  • 使用者 登录时间 是内置的Django 抽象用户 我不需要 (待实施)

  • 此外,您还可以实现 登录失败 以类似的方式。


ohrstrom
Reply   •   2 楼
ohrstrom    5 年前

您可以连接到提供的信号: django.contrib.auth.signals

记录到日志

import logging
from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed
from django.dispatch import receiver

log = logging.getLogger(__name__)

@receiver(user_logged_in)
def user_logged_in_callback(sender, request, user, **kwargs):    
    # to cover more complex cases:
    # http://stackoverflow.com/questions/4581789/how-do-i-get-user-ip-address-in-django
    ip = request.META.get('REMOTE_ADDR')

    log.debug('login user: {user} via ip: {ip}'.format(
        user=user,
        ip=ip
    ))

@receiver(user_logged_out)
def user_logged_out_callback(sender, request, user, **kwargs): 
    ip = request.META.get('REMOTE_ADDR')

    log.debug('logout user: {user} via ip: {ip}'.format(
        user=user,
        ip=ip
    ))

@receiver(user_login_failed)
def user_login_failed_callback(sender, credentials, **kwargs):
    log.warning('login failed for: {credentials}'.format(
        credentials=credentials,
    ))

记录到模型/数据库

因此,这个答案到目前为止还没有被接受——这里有一个例子,它在一个模型中而不是在日志中记录操作:

模型

# <your_app>/models.py

from django.db import models
from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed
from django.dispatch import receiver


class AuditEntry(models.Model):
    action = models.CharField(max_length=64)
    ip = models.GenericIPAddressField(null=True)
    username = models.CharField(max_length=256, null=True)

    def __unicode__(self):
        return '{0} - {1} - {2}'.format(self.action, self.username, self.ip)

    def __str__(self):
        return '{0} - {1} - {2}'.format(self.action, self.username, self.ip)


@receiver(user_logged_in)
def user_logged_in_callback(sender, request, user, **kwargs):  
    ip = request.META.get('REMOTE_ADDR')
    AuditEntry.objects.create(action='user_logged_in', ip=ip, username=user.username)


@receiver(user_logged_out)
def user_logged_out_callback(sender, request, user, **kwargs):  
    ip = request.META.get('REMOTE_ADDR')
    AuditEntry.objects.create(action='user_logged_out', ip=ip, username=user.username)


@receiver(user_login_failed)
def user_login_failed_callback(sender, credentials, **kwargs):
    AuditEntry.objects.create(action='user_login_failed', username=credentials.get('username', None))

管理

# <your_app>/admin.py
from django.contrib import admin
from models import AuditEntry

@admin.register(AuditEntry)
class AuditEntryAdmin(admin.ModelAdmin):
    list_display = ['action', 'username', 'ip',]
    list_filter = ['action',]