基于form表单和ajax的登录示例
作者:互联网
1 urls.py
from blog import views urlpatterns = [ url(r'^login/', views.login), url(r'^index/', views.index), #获取验证码图片的url url(r'^get_valid_img.png/', views.get_valid_img),
# 极验滑动验证码 获取验证码的url url(r'^pc-geetest/register', views.get_geetest), ]
2 views.py
from django.shortcuts import render, HttpResponse from django.http import JsonResponse from django.contrib import auth from geetest import GeetestLib # Create your views here. # VALID_CODE = "" # 自己生成验证码的登录 def login(request): # if request.is_ajax(): # 如果是AJAX请求 if request.method == "POST": # 初始化一个给AJAX返回的数据(只要是用ajax做前后端校验,后端视图函数就应该先定义一个小字典) ret = {"status": 0, "msg": ""} # 从提交过来的数据中 取到用户名和密码 username = request.POST.get("username") pwd = request.POST.get("password") valid_code = request.POST.get("valid_code") # 获取用户填写的验证码 print(valid_code) print("用户输入的验证码".center(120, "=")) #先校验验证码(可以区分大小写也可以不区分 不区分:统一转大写或者小写进行比对即可) if valid_code and valid_code.upper() == request.session.get("valid_code", "").upper(): # 验证码正确 # 利用auth模块做用户名和密码的校验 user = auth.authenticate(username=username, password=pwd) if user: # 用户名密码正确 # 登录成功记录当前用户状态 auth.login(request, user) ret["msg"] = "/index/" else: # 用户名密码错误 ret["status"] = 1 ret["msg"] = "用户名或密码错误!" else: ret["status"] = 1 ret["msg"] = "验证码错误" return JsonResponse(ret) return render(request, "login.html") # 使用极验滑动验证码的登录 # def login(request): # # if request.is_ajax(): # 如果是AJAX请求 # if request.method == "POST": # # 初始化一个给AJAX返回的数据 # ret = {"status": 0, "msg": ""} # # 从提交过来的数据中 取到用户名和密码 # username = request.POST.get("username") # pwd = request.POST.get("password") # # 获取极验 滑动验证码相关的参数 # gt = GeetestLib(pc_geetest_id, pc_geetest_key) # challenge = request.POST.get(gt.FN_CHALLENGE, '') # validate = request.POST.get(gt.FN_VALIDATE, '') # seccode = request.POST.get(gt.FN_SECCODE, '') # status = request.session[gt.GT_STATUS_SESSION_KEY] # user_id = request.session["user_id"] # # if status: # result = gt.success_validate(challenge, validate, seccode, user_id) # else: # result = gt.failback_validate(challenge, validate, seccode) # if result: # # 验证码正确 # # 利用auth模块做用户名和密码的校验 # user = auth.authenticate(username=username, password=pwd) # if user: # # 用户名密码正确 # # 给用户做登录 # auth.login(request, user) # ret["msg"] = "/index/" # else: # # 用户名密码错误 # ret["status"] = 1 # ret["msg"] = "用户名或密码错误!" # else: # ret["status"] = 1 # ret["msg"] = "验证码错误" # # return JsonResponse(ret) # return render(request, "login2.html") def index(request): return render(request, "index.html") # 获取验证码图片的视图 def get_valid_img(request): from PIL import Image, ImageDraw, ImageFont, ImageFilter #Image用来生成图片 ImageDraw在图片上写’字' ImageFont用来控制字体样式,ImageFilter让图片模糊化 import random # 获取随机颜色的函数 def get_random_color(): return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255) # 生成一个图片对象 img_obj = Image.new( 'RGB', (220, 35), get_random_color() ) # 在生成的图片上写字符 # 生成一个图片画笔对象 draw_obj = ImageDraw.Draw(img_obj) #你的画笔就可以在该图片上为所欲为 # 加载字体文件, 得到一个字体对象 font_obj = ImageFont.truetype("static/font/kumo.ttf", 28) # 开始生成随机字符串并且写到图片上 tmp_list = [] #定义一个变量存储最终验证码 for i in range(5): u = chr(random.randint(65, 90)) # 生成大写字母 l = chr(random.randint(97, 122)) # 生成小写字母 n = str(random.randint(0, 9)) # 生成数字,注意要转换成字符串类型 tmp = random.choice([u, l, n]) tmp_list.append(tmp) draw_obj.text((20+40*i, 0), tmp, fill=get_random_color(), font=font_obj) print("".join(tmp_list)) print("生成的验证码".center(120, "=")) # 不能保存到全局变量 # global VALID_CODE # VALID_CODE = "".join(tmp_list) # 将valid_code保存到session表中 request.session["valid_code"] = "".join(tmp_list) # 加干扰线 # width = 220 # 图片宽度(防止越界) # height = 35 # for i in range(5): # x1 = random.randint(0, width) # x2 = random.randint(0, width) # y1 = random.randint(0, height) # y2 = random.randint(0, height) # draw_obj.line((x1, y1, x2, y2), fill=get_random_color()) # # # 加干扰点 # for i in range(40): # draw_obj.point((random.randint(0, width), random.randint(0, height)), fill=get_random_color()) # x = random.randint(0, width) # y = random.randint(0, height) # draw_obj.arc((x, y, x+4, y+4), 0, 90, fill=get_random_color()) # # 将生成的图片保存在磁盘上 # with open("s10.png", "wb") as f: # img_obj.save(f, "png") # # 把刚才生成的图片返回给页面 # with open("s10.png", "rb") as f: # data = f.read() # 不需要在硬盘上保存文件,直接在内存中加载就可以 from io import BytesIO #能够帮你保存数据 并且在取的时候会以二进制的形式返回给你 #生成一个BytesIO对象 io_obj = BytesIO() #将生成的对象看成文件句柄 # 将生成的图片数据保存在io对象(内存管理器)中,需要指定图片格式 # img_obj = img_obj.filter(ImageFilter.BLUR) #让图片变的模糊 img_obj.save(io_obj, "png") # 从io对象里面取上一步保存的数据 data = io_obj.getvalue() return HttpResponse(data) # 请在官网申请ID使用,示例ID不可使用 pc_geetest_id = "b46d1900d0a894591916ea94ea91bd2c" pc_geetest_key = "36fc3fe98530eea08dfc6ce76e3d24c4" # 处理极验 获取验证码的视图 def get_geetest(request): user_id = 'test' gt = GeetestLib(pc_geetest_id, pc_geetest_key) status = gt.pre_process(user_id) request.session[gt.GT_STATUS_SESSION_KEY] = status request.session["user_id"] = user_id response_str = gt.get_response_str() return HttpResponse(response_str)
3 login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>欢迎登录</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/mystyle.css"> </head> <body> <div class="container"> <div class="row"> <form class="form-horizontal col-md-6 col-md-offset-3 login-form"> {% csrf_token %} <div class="form-group"> <label for="username" class="col-sm-2 control-label">用户名</label> <div class="col-sm-10"> <input type="text" class="form-control" id="username" name="username" placeholder="用户名"> </div> </div> <div class="form-group"> <label for="password" class="col-sm-2 control-label">密码</label> <div class="col-sm-10"> <input type="password" class="form-control" id="password" name="password" placeholder="密码"> </div> </div> <div class="form-group"> <label for="password" class="col-sm-2 control-label">验证码</label> <div class="col-sm-10"> <input type="text" name="valid_code" id="valid_code"> <img id="valid-img" class="valid-img" src="/get_valid_img.png?" alt=""> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="button" class="btn btn-default" id="login-button">登录</button> <span class="login-error"></span> </div> </div> </form> </div> </div> <script src="/static/jquery-3.3.1.js"></script> <script src="/static/bootstrap/js/bootstrap.min.js"></script> <script> $("#login-button").click(function () { // 1. 取到用户填写的用户名和密码 -> 取input框的值 var username = $("#username").val(); var password = $("#password").val(); var valid_code = $("#valid_code").val(); // 2. 用AJAX发送到服务端 $.ajax({ url: "/login/", type: "post", data: { "username": username, "password": password, "valid_code": valid_code, "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val() //"csrfmiddlewaretoken": '{{ csrf_token }}' }, success: function (data) { console.log(data); if (data.status) { // 有错误,在页面上提示 $(".login-error").text(data.msg); } else { // 登陆成功 location.href = data.msg; } } }) }); // 当input框获取焦点时将之前的错误清空 $("#username,#password").focus(function () { // 将之前的错误清空 $(".login-error").text(""); }); // 点击验证码图片 刷新验证码 $("#valid-img").click(function () { $(this)[0].src += "?"; }) </script> </body> </html>
4 login2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>欢迎登录</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/mystyle.css"> </head> <body> <div class="container"> <div class="row"> <form class="form-horizontal col-md-6 col-md-offset-3 login-form"> {% csrf_token %} <div class="form-group"> <label for="username" class="col-sm-2 control-label">用户名</label> <div class="col-sm-10"> <input type="text" class="form-control" id="username" name="username" placeholder="用户名"> </div> </div> <div class="form-group"> <label for="password" class="col-sm-2 control-label">密码</label> <div class="col-sm-10"> <input type="password" class="form-control" id="password" name="password" placeholder="密码"> </div> </div> <div class="form-group"> <!-- 放置极验的滑动验证码 --> <div id="popup-captcha"></div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="button" class="btn btn-default" id="login-button">登录</button> <span class="login-error"></span> </div> </div> </form> </div> </div> <script src="/static/jquery-3.3.1.js"></script> <script src="/static/bootstrap/js/bootstrap.min.js"></script> <!-- 引入封装了failback的接口--initGeetest --> <script src="http://static.geetest.com/static/tools/gt.js"></script> <script> // 极验 发送登录数据的 var handlerPopup = function (captchaObj) { // 成功的回调 captchaObj.onSuccess(function () { var validate = captchaObj.getValidate(); // 1. 取到用户填写的用户名和密码 -> 取input框的值 var username = $("#username").val(); var password = $("#password").val(); $.ajax({ url: "/login/", // 进行二次验证 type: "post", dataType: "json", data: { username: username, password: password, csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(), geetest_challenge: validate.geetest_challenge, geetest_validate: validate.geetest_validate, geetest_seccode: validate.geetest_seccode }, success: function (data) { console.log(data); if (data.status) { // 有错误,在页面上提示 $(".login-error").text(data.msg); } else { // 登陆成功 location.href = data.msg; } } }); }); $("#login-button").click(function () { captchaObj.show(); }); // 将验证码加到id为captcha的元素里 captchaObj.appendTo("#popup-captcha"); // 更多接口参考:http://www.geetest.com/install/sections/idx-client-sdk.html }; // 当input框获取焦点时将之前的错误清空 $("#username,#password").focus(function () { // 将之前的错误清空 $(".login-error").text(""); }); // 验证开始需要向网站主后台获取id,challenge,success(是否启用failback) $.ajax({ url: "/pc-geetest/register?t=" + (new Date()).getTime(), // 加随机数防止缓存 type: "get", dataType: "json", success: function (data) { // 使用initGeetest接口 // 参数1:配置参数 // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件 initGeetest({ gt: data.gt, challenge: data.challenge, product: "popup", // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效 offline: !data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注 // 更多配置参数请参见:http://www.geetest.com/install/sections/idx-client-sdk.html#config }, handlerPopup); } }) </script> </body> </html>
5 index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <h1>这是index页面!!!</h1> </body> </html>
标签:form,get,random,request,示例,geetest,验证码,ajax,data 来源: https://www.cnblogs.com/zh-xiaoyuan/p/12828144.html