我正在尝试设置用户可以“尝试”密码的次数。目前我想存储他/她可以尝试密码的次数和会话中的“惩罚时间”。
问题是用户关闭浏览器或更改另一个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和用户标志的组合,尚未测试,希望它可以正常工作
在用户登录之前,请检查:
代码:
##############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
如果他们的登录无效:
代码:
##############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()
答案 0 :(得分:4)
正如您在问题中提到的那样,只要SESSION_COOKIE_AGE
确定(默认为2周),Django中的会话就会自上次访问&#34;&#34;。
两个例外:
SESSION_EXPIRE_AT_BROWSER_CLOSE
手动设置为True
。在这种情况下,每次用户关闭浏览器时,会话都会清除但是理解会话ID存储在客户端的cookie中是非常重要的,因此用户很容易删除其cookie,然后Django服务器会认为这是一个新的会话。
实现所需内容的另一种方法是将这些数据保存在用户身上 - 这意味着,在用户user@example.com
以几次错误尝试登录后,您可以将该用户名标记为禁止X分钟。您需要一个不同的数据库表来保存该信息和您自己的逻辑。我目前不知道应用程序会这样做,但快速搜索可能证明我错了。
这样,即使用户清除了他的会话,服务器也不会允许用户登录。