Django - 会话持续多长时间(如果用户关闭并重新打开浏览器)



我正在尝试设置用户可以"尝试"密码的次数。目前,我想存储他/她可以尝试密码的次数和会话中的"惩罚时间"。

问题是用户关闭浏览器或更改另一个 IP 地址会影响会话吗?

例如,如果用户的惩罚时间为 5 分钟,这可以通过两个日期时间实例减去 5 来完成>然后让用户重试 5 次。如果用户在此期间关闭并重新打开浏览器,"会话"是否会丢失?

在用户登录之前进行检查:

##############SESSION BASED##################
#Initialize tries, to be used later on
tries = "0"
try:
    tries = request.session['tries']
except:
    pass
#If tries > 5 times
if(int(tries) >= 5):
    timeNow = request.session['locked_time']
    timeDifferenceSeconds = (datetime.datetime.now() - datetime.datetime.strptime(timeNow, "%Y-%m-%d %H:%M:%S.%f")).total_seconds()
    #See if the difference is greater than 15 minutes, otherwise lock
    if(timeDifferenceSeconds > 900):
        request.session['tries'] = str(0)
        logger.info("User:" + str(username) + " is unlocked");
    else:
        logger.info("User:" + str(username) + " is currently locked");
        logger.info("User:" + str(username) + " returning Locked");
        return HttpResponse("Locked")
##############SESSION BASED##################

用户获得无效登录后:

##############SESSION BASED##################
#if the user fails in providing the correct username/password, increment tries
try:
    tries = request.session['tries']
    num = int(tries) 
    num += 1
    tries = str(num)
    request.session['tries'] = str(tries)
except:
    tries = 0
    request.session['tries'] = str(tries)
#If tries > 5, then we will lock
if(int(tries) >= 5):
    logger.info("User:" + str(username) + " is not valid, current tries:" + str(tries) + " and will be locked");
    request.session['locked_time'] = str(datetime.datetime.now())
    logger.info("User:" + str(username) + " returning Locked");
    return HttpResponse("Locked")
else:
    logger.info("User:" + str(username) + " is not valid, current tries:" + str(tries));
    logger.info("User:" + str(username) + " returning Invalid");
    return HttpResponse("Invalid")
##############SESSION BASED##################

目前我没有SESSION_COOKIE_AGE更改,因此目前默认为2周。

更新:

使用了IP和用户标志的组合,尚未对其进行测试,希望它有效

在用户登录之前,请检查:

  1. 他们的IP地址,如果他们在"可疑表"中,如果帐户超过10个,那么他们就无法登录
  2. 检查尝试次数,如果大于 5,则我们锁定它们 15 分钟乘以它们的违规行为(尝试次数超过 5 次(

法典:

##############USER BASED AUTHENTICATION SYSTEM#####################
#Test for the user's public IP or best matched IP to see if it is banned
realIP = get_real_ip(request)
IP = get_ip(request)
#Get their realIP, and see if it matches, if they have over 10 accounts, then they are banned
try:
    suspiciousIP = suspicousIP.objects.get(pk=realIP)
    if(suspiciousIP.count > 10):
        logger.info("User:" + str(username) + " has a banned real IP")
        logger.info("User:" + str(username) + " returning Banned");
        return HttpResponse("Banned")
except:
    pass
#Get their IP, and see if it matches, if they have over 10 accounts, then they are banned
try:
    suspiciousIP = suspicousIP.objects.get(pk=IP)
    if(suspiciousIP.count > 10):
        logger.info("User:" + str(username) + " has a banned IP")
        logger.info("User:" + str(username) + " returning Banned");
        return HttpResponse("Banned")
except:
    pass
#Test the current user's blockedList
#2 conditions, if lockedTemp = True, then it is temporary locked until user has unlocked it
#by clicking the unlock email
#The other condition is whether tries > 5, and violations <= 5 (at 5th violation, the lockedTemp = true)
#then the user would need to wait until the time is over (900 seconds), which increases by each violation
userObject = None
try:
    userObject = blockedList.objects.get(pk=username)
    currentDateTime = datetime.datetime.now()
    objectDateTime = datetime.datetime.strptime(str(userObject.dateTime), "%Y-%m-%d %H:%M:%S.%f")
    lockedTemp = userObject.lockedTemp
    tries = userObject.tries
    violations = userObject.violations
    if(lockedTemp == "True"):
        logger.info("User:" + str(username) + " is temp locked");
        logger.info("User:" + str(username) + " returning tempLock");
        return HttpResponse("tempLock")
    elif (tries >= 5 and violations <= 5 and lockedTemp != "True"):
        timeDifferenceSeconds = (currentDateTime - objectDateTime).total_seconds()
        if(timeDifferenceSeconds > 900 * violations):
            userObject.tries = 0
            userObject.save(update_field=['tries'])
            logger.info("User:" + str(username) + " is unlocked, with tries:" + str(tries) + ", violations:" + str(violations))
        else:
            logger.info("User:" + str(username) + " is currently locked, with tries:" + str(tries) + ", violations:" + str(violations))
            logger.info("User:" + str(username) + " returning Locked");
            return HttpResponse("Locked")
except:
    pass
##############USER BASED AUTHENTICATION SYSTEM#####################

成功登录后:删除其阻止列表和可疑 IP 条目

#See if the user's remember me is checked, if it is not checked, then
#the session cookie will automatically expire when the browser closes
if(rememberMe == "true"):
    request.session.set_expiry(86400)
    logger.info("User:" + str(username) + " has set their expiration to 1 day")
else:
    request.session.set_expiry(0)
    logger.info("User:" + str(username) + " has set their expiration to expire when browser closes")
#See if the user is marked in blockedList, if true, then delete their row
try:
    userObject = blockedList.objects.get(pk=username)
    userObject.delete()
    logger.info("User:" + str(username) + " is in blockedList, removing their entry")
except:
    logger.info("User:" + str(username) + " is NOT in blockedList")
    pass
#See if the user's real IP is marked in suspicious IP, if true, then remove their entry
try:
    suspiciousIP = suspicousIP.objects.get(pk=realIP)
    suspiciousIP.delete()
    logger.info("User:" + str(username) + " is in suspicious real IP, removing their entry")
except:
    pass
#See if the user's IP is marked in suspicious IP, if true, then remove their entry
try:
    suspiciousIP = suspicousIP.objects.get(pk=IP)
    suspiciousIP.delete()
    logger.info("User:" + str(username) + " is in suspicious IP, removing their entry")
except:
    pass

如果他们的登录无效:

  1. 增加尝试次数,如果尝试> 5,则它们被锁定,"时间测试"它们在 dateTime 上的锁定将在登录前发生
  2. 如果他们有超过 5 次违规行为,则该帐户将被锁定,直到用户通过单击发送给我们的自动生成的电子邮件中的链接将其解锁

法典:

##############USER BASED AUTHENTICATION SYSTEM#####################
try:
    #Get their current object, if exists, and increase their tries
    userObject = blockedList.objects.get(pk=username)
    userObject.tries += 1
    #If their tries >= 5, then lock them temporary, and increase violation
    if(userObject.tries >= 5):
        logger.info("User:" + str(username) + " is not valid, current tries:" + str(userObject.tries) + " and will be locked");
        userObject.violation += 1
        userObject.dateTime = str(dateTime.dateTime.now())
        #If violation >= 5, then we will tempLock, and can only be unlocked by email
        if(userObject.violation >= 5):
            logger.info("User:" + str(username) + " is not valid, will get TempLocked");
            userObject.lockedTemp = "True"
            userObject.save()
            #Get their suspicious Real IPs, and increase them, or make a new one
            try:
                suspiciousIP = suspicousIP.objects.get(pk=realIP)
                suspiciousIP.count += 1
                suspiciousIP.save()
                logger.info("User:" + str(username) + " has a suspeciousIP:" + str(suspiciousIP) + " current count:" + str(suspiciousIP.count));
            except:
                if realIP is not None:
                    newSuspiciousIP = suspicousIP(IP = realIP)
                    newSuspiciousIP.save()
                    logger.info("User:" + str(username) + " has a new suspeciousIP:" + str(realIP));
            #Get their suspicious IPs, and increase them, or make a new one
            try:
                suspiciousIP = suspicousIP.objects.get(pk=IP)
                suspiciousIP.count += 1
                suspiciousIP.save()
                logger.info("User:" + str(username) + " has a suspeciousIP:" + str(suspiciousIP) + " current count:" + str(suspiciousIP.count));
            except:
                if IP is not None:
                    newSuspiciousIP = suspicousIP(IP = IP)
                    newSuspiciousIP.save()
                    logger.info("User:" + str(username) + " has a new suspeciousIP:" + str(IP));
            logger.info("User:" + str(username) + " returning tempLock");
            logger.info("User:" + str(username) + " returning tempLock");
            return HttpResponse("tempLock")
    userObject.save()
    logger.info("User:" + str(username) + " returning Locked");
    return HttpResponse("Locked")
except:
    newUsername = username
    newRealIP = realIP
    newIP = IP
    newDateTime = ""
    newTries = 1
    newViolations = 0
    newLockedTemp = "False"
    newUserObject = blockedList(username=newUsername, realIP=newRealIP, IP = newIP,
                                dateTime = newDateTime, tries = newTries, violations = newViolations,
                                lockedTemp = newLockedTemp)
    newUserObject.save()
    logger.info("User:" + str(username) + " returning Invalid");
    return HttpResponse("Invalid")
##############USER BASED AUTHENTICATION SYSTEM#####################

使用的额外模型:

class blockedList(models.Model):
    username = models.CharField(max_length=200, primary_key=True)
    realIP = models.CharField(max_length=200)
    IP = models.CharField(max_length=200)
    dateTime = models.CharField(max_length=200)
    tries = models.IntegerField()
    violations = models.IntegerField()
    lockedTemp = models.CharField(max_length=200)
class suspicousIP(models.Model):
    IP = models.CharField(max_length=200, primary_key=True)
    count = models.IntegerField()

正如你在问题中提到的,只要 SESSION_COOKIE_AGE 确定(默认为 2 周(从上次"访问"开始,Django 中的会话就会存在。

有两个例外:

  • 您可以自己为会话设置到期时间,然后取决于关于这一点。
  • SESSION_EXPIRE_AT_BROWSER_CLOSE设置手动设置为 True 。在这种情况下,每次用户关闭浏览器时,会话都会清除

但是了解会话 ID 存储在客户端的 cookie 中非常重要,因此用户很容易删除其 cookie,然后 Django 服务器会将其视为新会话。

实现您想要的另一种方法是将这些数据保存在用户身上 - 这意味着,在几次错误尝试以用户user@example.com身份登录后,您可以将该用户名标记为禁止 X 分钟。您需要一个不同的数据库表来保存该信息和您自己的逻辑。我目前不知道有哪个应用程序可以做到这一点,但快速搜索可能会证明我错了。

这样,即使用户清除了他的会话,服务器也不会允许用户登录。

相关内容

最新更新