Python Django日志登录尝试和3次失败尝试后锁定用户

Python Django日志登录尝试和3次失败尝试后锁定用户,python,django,Python,Django,所以我对Django很陌生。实际上是我的第一个项目 我想创建一个自定义模型“Logging”,我想在其中记录管理员登录尝试并计算尝试次数。在3次登录尝试失败后,用户必须将我锁定。我已经创建了这样的自定义用户模型 class UserManager(BaseUserManager): def create_user(self,username,password,description): if not username: raise ValueError('Users mu

所以我对Django很陌生。实际上是我的第一个项目

我想创建一个自定义模型“Logging”,我想在其中记录管理员登录尝试并计算尝试次数。在3次登录尝试失败后,用户必须将我锁定。我已经创建了这样的自定义用户模型

class UserManager(BaseUserManager):
def create_user(self,username,password,description):
    if not username:
        raise ValueError('Users must have an username ')

    user = self.model(username=username)
    user.set_password(password)
    user.description = description
    user.save(using=self._db)
    return user

def create_staffuser(self, username, password, description):
    user = self.create_user(
        username,
        password,
        description
    )
    user.staff = True
    user.save(using=self._db)
    return user

def create_superuser(self, username, password, description):
    user = self.model(username=username)
    user.set_password(password)
    user.description = description
    user.staff = True
    user.admin = True
    user.save(using=self._db)
    return user
class Users(AbstractBaseUser):
username = models.CharField(max_length=15,unique=True)
description = models.CharField(max_length=50,default="None")

is_active = models.BooleanField(default=True)
staff = models.BooleanField(default=False) # a admin user; non super-user
admin = models.BooleanField(default=False) # a superuser

# notice the absence of a "Password field", that is built in.

USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['description']

def get_full_name(self):
    return self.username

def get_short_name(self):
    return self.username

def __str__(self):
    return self.username

def has_perm(self, perm, obj=None):
    "Does the user have a specific permission?"
    # Simplest possible answer: Yes, always
    return True

def has_module_perms(self, app_label):
    "Does the user have permissions to view the app `app_label`?"
    # Simplest possible answer: Yes, always
    return True

@property
def is_staff(self):
    "Is the user a member of staff?"
    return self.staff

@property
def is_admin(self):
    "Is the user a admin member?"
    return self.admin
    
objects = UserManager()

那么如何记录自定义管理员尝试?

您可以为和信号制作信号接收器。因此,我们可以创建一个如下所示的模型:

from django.conf import settings

class FailedLogin(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE
    )
    timestamp = models.DateTimeField(auto_now_add=True)
然后我们定义了两个信号接收器,一个用于成功登录,将删除
FailedLogin
记录(如果有):

从django.contrib.auth导入get\u user\u模型
从django.contrib.auth.signals导入用户登录,用户登录失败
从django.dispatch导入接收方
@接收器(用户已登录)
def user_logged_recv(发送方、请求、用户,**kwargs):
FailedLogin.objects.filter(用户=用户).delete()失败
@接收方(用户登录失败)
def用户登录失败(发件人、凭据、请求):
User=get\u User\u model()
尝试:
u=User.objects.get(username=credentials.get('username'))
#存在具有给定用户名的用户
FailedLogin.objects.create(用户=u)
如果失败登录.objects.filter(用户=u).count()>=3:
#尝试三次或更多,禁用用户
u、 是否激活=错误
u、 保存()
除User.DoesNotExist外:
#找不到用户,我们无法执行任何操作

pass
您可以为和信号制作接收器。您可以始终使用时间戳将尝试添加到数据库中。这样,你就可以让他们只有在时间足够近的情况下才会被踢出。也就是说,如果一个用户打算用一个不存在的用户名登录,你就不能为该用户登录,因为该用户是。。。未知..非常感谢。你帮我学习了信号,它确实起了作用。
from django.contrib.auth import get_user_model
from django.contrib.auth.signals import user_logged_in, user_login_failed
from django.dispatch import receiver

@receiver(user_logged_in)
def user_logged_recv(sender, request, user, **kwargs):
    FailedLogin.objects.filter(user=user).delete()

@receiver(user_login_failed)
def user_login_failed_recv(sender, credentials, request):
    User = get_user_model()
    try:
        u = User.objects.get(username=credentials.get('username'))
        # there is a user with the given username
        FailedLogin.objects.create(user=u)
        if FailedLogin.objects.filter(user=u).count() >= 3:
            # three tries or more, disactivate the user
            u.is_active = False
            u.save()
    except User.DoesNotExist:
        # user not found, we can not do anything
        pass