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

时间:2014-09-08 05:15:48

标签: python django session

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

问题是用户关闭浏览器或更改另一个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次)
  3. 代码:

    ##############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#####################
    

    成功登录后:删除他们的blockedList和SuspiciousIP条目

    #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. 增量尝试,如果尝试&gt; 5,然后他们被锁定,“时间测试”他们在dateTime上的锁定将在登录之前发生
    2. 如果他们的违规次数超过5次,则该帐户将被锁定,直到用户通过点击发送给我们的自动生成的电子邮件中的链接解锁该帐户
    3. 代码:

      ##############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()
      

1 个答案:

答案 0 :(得分:4)

正如您在问题中提到的那样,只要SESSION_COOKIE_AGE确定(默认为2周),Django中的会话就会自上次访问&#34;&#34;。

两个例外:

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

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

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

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