Djangoでのすべてのユーザーログインとログアウトの試行を記録したいと思います。このレコードには、ログイン/ログアウトしたすべてのユーザーの履歴、IPアドレス、ログイン/ログアウトの時間が表示されます。
Django_admin_log
テーブルは、他のモデルのADD/DELETE/CHANGEアクティビティのみを記録し、ユーザーアクセスの履歴は記録しないようです。また、user_logged_in
、user_logged_out
の信号も確認しました。これらの信号を使用する場合、すべてのユーザーのログイン/ログアウトの履歴を記録する新しいテーブルを作成する必要があるようです。 Djangoこれを行うための組み込みメソッドはありますか?または利用可能なパッケージ?他のパッケージをチェックしましたが、ログイン試行に関連するものは失敗した試行のみを制限しますが、記録しません成功したログイン/ログアウト。
提供されたシグナルにフックすることができます: 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('logout 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',]
以下のようにDjango user(AbstractUser
)と統合された新しい回答があります。
model.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)
Signal.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
フィールドの1つにあります。
ユーザーログイン時間は組み込みDjango AbstractUser
。(実装する必要はありません)
また、同様の方法でlogin_faildを実装できます。