Share what today django account password, front-end send ajax request, sends the user name and password information to back-end processing, back-end data will be sent from the front of the filter matched with a database, specify the page jump success, otherwise put phase corresponding error message is returned, while adding a small function exceeds a predetermined number of logins within the specified time, it could not land locked, and then wait for the next period of time to allow the landing.
First, create a table by the historical landing ORM
class login_history(models.Model):
user = models.CharField(max_length=32, verbose_name='登录用户')
ip = models.GenericIPAddressField(verbose_name='用户IP地址')
count = models.SmallIntegerField(verbose_name='登录次数')
lock = models.SmallIntegerField(verbose_name='锁')
utime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = "login_history"
verbose_name = "历史登录"
verbose_name_plural = "历史登录"
def __str__(self):
return self.user
Second, the front-end code shows with pictures
Front-end code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> - 登录</title>
<meta name="keywords" content="">
<meta name="description" content="">
<link rel="shortcut icon" href="/static/favicon.ico">
{% include 'css_comm.html' %}
</head>
<body class="gray-bg">
<div class="middle-box text-center loginscreen animated fadeInDown" >
<div style="margin-top: 40px">
<h3>欢迎使用 AutoOps</h3>
{% csrf_token %}
<div class="form-group" >
<input type="text" name="user" value="" class="form-control user_obj" placeholder="用户名" required="" autocomplete="off">
</div>
<span style="display: block;margin-bottom: 10px;color:red" id="user_error"></span>
<div class="form-group">
<input type="password" name="pwd" value="" class="form-control pwd_obj" placeholder="密码" required="" autocomplete="off">
</div>
<span style="display: block;margin-bottom: 10px;color:red" id="pwd_error"></span>
<button type="submit" class="btn btn-info block full-width m-b btn_obj">登 录</button>
记住密码 <input type="checkbox" style="margin: 0">
</div>
</div>
{% include 'js_comm.html' %}
<script>
$(".btn_obj").click(function () {
var user = $(".user_obj").val();
var pwd = $(".pwd_obj").val();
$.ajaxSetup({headers: {"X-CSRFToken": '{{ csrf_token }}'}});
$.ajax({
"url": "/login.html",
"type": "post",
"data": {"user":user,"pwd":pwd},
success: function (data) {
var obj = JSON.parse(data);
if (obj.status) {
$(".user_obj").css("border-color","");
$("#user_error").text("");
$(".pwd_obj").css("border-color","");
$("#pwd_error").text("");
window.location.href = '/assets/assets_list.html';
}
else {
if (obj.error.user_error != "") {
$(".user_obj").css("border-color","red");
$("#user_error").text(obj.error.user_error);
}else {
$(".user_obj").css("border-color","");
$("#user_error").text("");
}
if (obj.error.pwd_error != "") {
$(".pwd_obj").css("border-color","red");
$("#pwd_error").text(obj.error.pwd_error);
}else {
$(".pwd_obj").css("border-color","");
$("#pwd_error").text("");
}
if (obj.error.login_error != "") {
alert("登录失败",obj.error.login_error, "", {type: 'error'})
}
}
}
})
})
</script>
</body>
</html>
Back-end code
def login(request):
ret = {"status": False, "error": {"user_error": "", "pwd_error": "", "login_error": ""}}
if request.method == "POST":
user = request.POST.get("user") #获取用户名
pwd = request.POST.get("pwd") #获取密码
if request.META['REMOTE_ADDR']: #判断是否获取用户IP地址
access_ip = request.META['REMOTE_ADDR'] #存到access_ip变量中
else:
access_ip = request.META['HTTP_X_FORWARDED_FOR'] #获取用户的真实IP,非代理IP
if access_ip:
ip_obj = models.login_history.objects.filter(ip=access_ip).first() #在历史登录表中查找是否有这个IP
if ip_obj:
current_time = datetime.datetime.now() #获取当前时间
second = current_time - ip_obj.utime #用当前时间减去最近登录的时间
second = second.seconds #转换为秒数
count = ip_obj.count #获取当前对象的登录次数
count = count + 1 #次数加1
ip_obj.count = count #修改次数信息
ip_obj.save() #保存
if second < 60 and count >= 10: #判断秒数是否小于60秒并且次数大于等于10
ret["error"]["login_error"] = "过于频繁登录,你已经被锁着,等一会60秒之后再登录"
ip_obj.user = user #登录的用户名
ip_obj.lock = 1 #值为1表示锁着
ip_obj.save() #保存
return HttpResponse(json.dumps(ret)) #返回给前端
elif ip_obj.lock == 1 and second >= 60: #判断lock是否等于1和秒数大于60秒
ip_obj.lock = 0 #值为0表示解锁
ip_obj.count = 1 #初始化登录次数
ip_obj.save() #保存
else:
models.login_history.objects.create(user=user, ip=access_ip, count=1, lock=0) #没有登录过,就创建记录
if user:
account_obj = Account.objects.filter(username=user).first() #判断这个用户名是否存在
if not account_obj:
ret["error"]["user_error"] = "用户名错误或者不存在"
else:
ret["error"]["user_error"] = "用户名不能为空"
if pwd == "":
ret["error"]["pwd_error"] = "密码不能为空"
users = authenticate(username=user, password=pwd) #验证用户名和密码是否一样
if users:
request.session["user_id"] = users.pk #存储到session会话中
initial_session(users, request)
ret["status"] = True
ip_obj.count = 1 # 登录次数等于1
ip_obj.save()
return HttpResponse(json.dumps(ret)) #返回前端
else:
ret["error"]["pwd_error"] = "用户名或密码不正确"
return HttpResponse(json.dumps(ret))
return render(request, "login.html")
Third, the test results
1. Do not enter your login account password, will prompt an error message
2. Enter the user does not exist
3. Enter the wrong password
4. Within 60 seconds 10 times in a row wrong password, you can allow a malicious login, locked can not let their login
5. Review the database table information
6. Finally demonstrate successful login Jump map