功能1: 基于用户认证组件和Ajax实现登录验证(图片验证码)
总结:
1 一次请求伴随多次请求
2 PIL
3 session存储
4 验证码刷新
步骤:
1、配置静态文件夹
settings.py
STATICFILES_DIRS=[
os.path.join(BASE_DIR,"static"),
]
---
登录页面的设计
label标签的id属性,点击label标记,相当于点击了input框 bootstarp样式 class="form-group" class="form-control"
Bootstrap 表单
Bootstrap 提供了下列类型的表单布局: 垂直表单(默认) 内联表单 水平表单 垂直或基本表单 基本的表单结构是 Bootstrap 自带的,个别的表单控件自动接收一些全局样式。下面列出了创建基本表单的步骤: 向父 <form> 元素添加 role="form"。 把标签和控件放在一个带有 class .form-group 的 <div> 中。这是获取最佳间距所必需的。
向所有的文本元素 <input>、<textarea> 和 <select> 添加 class ="form-control" 。
form-control
表单控件加上类form-control后,效果为: 宽度为100% 设置边框为浅灰色 控件具有4px的圆角 设置阴影效果,元素得到焦点时,阴影和边框效果会发生变化 设置placeholder的颜色为#999
login布局:
动态生成验证码
(1)方式1:HttpResponse返回字符串
views.py
def get_validCode_img(request): # 方式一: with open('content1.png','rb')as f: data=f.read() return HttpResponse(data)
from blog import views urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('get_validCode_img/', views.get_validCode_img), ]
-----
(2)方式2:引入PIL模块 pip install pillow
def get_validCode_img(request): # # 方式一: # with open('content1.png','rb')as f: # data=f.read() # return HttpResponse(data) # 方式二 # pip install pillow # python下的图像处理模块
先把图片加载到磁盘上,再从磁盘读取内容返回给浏览器
import random def get_random_color(): return (random.randint(0,255),random.randint(0,255),random.randint(0,255)) from PIL import Image img=Image.new('RGB',(270,34),color=get_random_color()) with open('validcode.png','wb') as f: img.save(f,'png') with open('validcode.png', 'rb') as f: data=f.read() return HttpResponse(data)
(3)方式3:内存处理
def get_validCode_img(request): # 方式三 内存处理 import random def get_random_color(): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) from PIL import Image from io import BytesIO img = Image.new('RGB', (270, 34), color=get_random_color()) f=BytesIO() img.save(f,'png') data=f.getvalue() return HttpResponse(data)
可以达到同样的效果
(4)方式4:加入噪点的,字体的
下载ttf载体放入静态文件中
def get_validCode_img(request): # 方式四 import random,string def get_random_color(): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) from PIL import Image,ImageDraw,ImageFont from io import BytesIO
img = Image.new('RGB', (270, 34), color=get_random_color()) # 画笔 draw draw=ImageDraw.Draw(img) kumo_font=ImageFont.truetype('static/font/kumo.ttf',size=32) code='' for i in range(5): random_num=random.randint(0,9) random_low_alpha=chr(random.randint(65, 90)) random_upper_alpha=chr(random.randint(97, 122)) add=random.choice([random_num,random_low_alpha,random_upper_alpha])
# add2=random.choice(string.ascii_letters+string.digits) # code = ''.join([code,str(add)]) draw.text((i*50+20,5),str(add),get_random_color(),font=kumo_font)#画文字 # draw.line()#画线 # draw.point()#画点 # 补充噪点噪线 防止机器识别 # 噪线 width, height = 210, 35 for i in range(5): x1 = random.randint(0, width) x2 = random.randint(0, width) y1 = random.randint(0, width) y2 = random.randint(0, width) draw.line((x1, y1, x2, y2), fill=get_random_color()) # 噪点 for i in range(100): draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color()) x = random.randint(0, width) y = random.randint(0, height) draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color())
# 内存处理 f = BytesIO() img.save(f,'png') data = f.getvalue() return HttpResponse(data)
验证码的刷新与字符串保存,验证码解耦
点击验证码刷新
在静态文件中加入js引入jQuery
login.html
<script type="text/javascript" src="/static/JS/jquery-3.2.1.min.js"></script> <script type="text/javascript"> //刷新验证码 $(function () { $("#id_valid_code_img").click(function () { $(this)[0].src+="?" }) }) </script>点击图片出现刷新效果:
保存验证码字符串--验证输入的验证码
login.html
// 登录验证 $('.login-btn').click(function () { $.ajax( { url:'', type:'post', data:{user:$('#username').val(),pwd:$('#password').val(),valid_code:$('#id_valid_code_str').val(), {# {% csrf_token %}#} csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()}, success:function (data) { console.log(data) } }) })
-----
from django.shortcuts import render # Create your views here. from django.shortcuts import render,HttpResponse # Create your views here. from django.http import JsonResponse
def login(request): if request.method=='POST':
response={'user':None,'msg':None}
user=request.POST.get('user') pwd=request.POST.get('pwd')
# 读取提交的验证码 valid_code=request.POST.get('valid_code')
# 会话跟踪技术,读取生成验证码时---保存验证码 valid_code_str=request.session.get('valid_code_str')
# 如果书写的验证码和生成的验证码一致 # 不区分大小写---可以统一变成大写 if valid_code.upper()==valid_code_str.upper(): pass else: response['msg']='valid code error!' return JsonResponse(response) # ajax返回一个响应字符串 return render(request,'login.html') def get_validCode_img(request): # 方式四 import random,string def get_random_color(): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) from PIL import Image,ImageDraw,ImageFont from io import BytesIO img = Image.new('RGB', (270, 34), color=get_random_color()) # 画笔 draw draw=ImageDraw.Draw(img) kumo_font=ImageFont.truetype('static/font/kumo.ttf',size=32) code='' valid_code_str='' for i in range(5): random_num=random.randint(0,9) random_low_alpha=chr(random.randint(65, 90)) random_upper_alpha=chr(random.randint(97, 122)) add=random.choice([random_num,random_low_alpha,random_upper_alpha]) # add2=random.choice(string.ascii_letters+string.digits) # code = ''.join([code,str(add)]) draw.text((i*50+20,5),str(add),get_random_color(),font=kumo_font)#画文字 # 保存验证码字符串 valid_code_str+=str(add) # draw.line()#画线 # draw.point()#画点 # 补充噪点噪线 防止机器识别 print(valid_code_str)
#生成的字符串---验证码 valid_code_str
request.session['valid_code_str']=valid_code_str ''' 1 assdd 2 COOKIE {'sessionid':assdd } session-key session-data ''' f = BytesIO() img.save(f,'png') data = f.getvalue() return HttpResponse(data)
https://www.cnblogs.com/foremostxl/p/9978842.html
博客系统之登陆认证
创建超级用户 python manage.py createsuperuser
用户认证auth模块,ajax信息response
# 用户认证模块 from django.contrib import auth
def login(request): if request.method=='POST': response={'user':None,'msg':None} user=request.POST.get('user') pwd=request.POST.get('pwd') # 读取验证码 valid_code=request.POST.get('valid_code') # 回话跟踪技术,保存验证码 valid_code_str=request.session.get('valid_code_str') # 如果书写的验证码和生成的验证码一致 # 不区分大小写---可以统一变成大写 if valid_code.upper()==valid_code_str.upper(): user=auth.authenticate(username=user,password=pwd) if user: auth.login(request,user)# request.user==当前登录对象 response['user']=user.username else: response['msg']='username or password error' else: response['msg']='valid code error!' return JsonResponse(response) # ajax返回一个响应字符串 return render(request,'login.html')
login
ajax success成功执行
/ 登录验证 $('.login-btn').click(function () { $.ajax( { url:'', type:'post', data:{user:$('#username').val(),pwd:$('#password').val(),valid_code:$('#id_valid_code_str').val(), {# {% csrf_token %}#} csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()}, success:function (data) { console.log(data); if(data.user){ location.href='/index' } else { $('.error').text(data.msg).css({'color':'red','margin-left':'10px'}) } } })
代码优化:错误信息1s后消失
功能一总结:
代码优化:错误信息1s后消失
整体代码:
from django.shortcuts import render # Create your views here. from django.shortcuts import render,HttpResponse # Create your views here. # 用户认证模块 from django.contrib import auth from django.http import JsonResponse def login(request): if request.method=='POST': response={'user':None,'msg':None} user=request.POST.get('user') pwd=request.POST.get('pwd') # 读取验证码 valid_code=request.POST.get('valid_code') # 回话跟踪技术,保存验证码 valid_code_str=request.session.get('valid_code_str') # 如果书写的验证码和生成的验证码一致 # 不区分大小写---可以统一变成大写 if valid_code.upper()==valid_code_str.upper(): user=auth.authenticate(username=user,password=pwd) if user: auth.login(request,user)# request.user==当前登录对象 response['user']=user.username else: response['msg']='username or password error' else: response['msg']='valid code error!' return JsonResponse(response) # ajax返回一个响应字符串 return render(request,'login.html') def get_validCode_img(request): # # 方式一: # with open('content1.png','rb')as f: # data=f.read() # return HttpResponse(data) # 方式二 # pip install pillow # python下的图像处理模块 # import random # def get_random_color(): # return (random.randint(0,255),random.randint(0,255),random.randint(0,255)) # from PIL import Image # img=Image.new('RGB',(270,34),color=get_random_color()) # with open('validcode.png','wb') as f: # img.save(f,'png') # with open('validcode.png', 'rb') as f: # data=f.read() # # return HttpResponse(data) # 方式三 内存处理 # import random # def get_random_color(): # return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) # # from PIL import Image # from io import BytesIO # img = Image.new('RGB', (270, 34), color=get_random_color()) # f=BytesIO() # img.save(f,'png') # data=f.getvalue() # return HttpResponse(data) # 方式四 import random,string def get_random_color(): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) from PIL import Image,ImageDraw,ImageFont from io import BytesIO img = Image.new('RGB', (270, 34), color=get_random_color()) # 画笔 draw draw=ImageDraw.Draw(img) kumo_font=ImageFont.truetype('static/font/kumo.ttf',size=32) code='' valid_code_str='' for i in range(5): random_num=random.randint(0,9) random_low_alpha=chr(random.randint(65, 90)) random_upper_alpha=chr(random.randint(97, 122)) add=random.choice([random_num,random_low_alpha,random_upper_alpha]) # add2=random.choice(string.ascii_letters+string.digits) # code = ''.join([code,str(add)]) draw.text((i*50+20,5),str(add),get_random_color(),font=kumo_font)#画文字 # 保存验证码字符串 valid_code_str+=str(add) # draw.line()#画线 # draw.point()#画点 # 补充噪点噪线 防止机器识别 # 噪线 width, height = 210, 35 for i in range(2): x1 = random.randint(0, width) x2 = random.randint(0, width) y1 = random.randint(0, width) y2 = random.randint(0, width) draw.line((x1, y1, x2, y2), fill=get_random_color()) # 噪点 for i in range(50): draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color()) x = random.randint(0, width) y = random.randint(0, height) draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color()) print(valid_code_str) #生成的字符串---验证码 valid_code_str request.session['valid_code_str']=valid_code_str ''' 1 assdd 2 COOKIE {'sessionid':assdd } session-key session-data ''' f = BytesIO() img.save(f,'png') data = f.getvalue() return HttpResponse(data) def index(request): return render(request,'index.html',locals())
from django.contrib import admin from django.urls import path from blog import views urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), path('get_validCode_img/', views.get_validCode_img), ]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/blog/bootstrap-3.3.7/css/bootstrap.css"> </head> <body> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <form> {% csrf_token %} <h3 class="col-md-offset-5">登录页面</h3> <div class="form-group "> <label for="username">username</label> <input type="text" class="form-control " placeholder="username" id="username"> </div> <div class="form-group "> <label for="password">Password</label> <input type="password" class="form-control " id="password" placeholder="Password"> </div> <div class="form-group"> <label for="id_valid_code_str">验证码</label> <div class="row "> <div class="col-md-6"> <input type="text" id="id_valid_code_str" class="form-control"> </div> <div class="col-md-6"> <img src="/get_validCode_img/" id="id_valid_code_img" width="270" height="34" title="验证码" alt=""> </div> </div> </div> <div class="form-group"> <input type="button" class="btn btn-default login-btn pull-right" value="登录"><span class="error"></span> </div> </form> </div> </div> </div> <script type="text/javascript" src="/static/JS/jquery-3.2.1.min.js"></script> <script type="text/javascript"> //刷新验证码 $(function () { $("#id_valid_code_img").click(function () { $(this)[0].src+="?" }) }); // 登录验证 $('.login-btn').click(function () { $.ajax( { url:'', type:'post', data:{user:$('#username').val(),pwd:$('#password').val(),valid_code:$('#id_valid_code_str').val(), {# {% csrf_token %}#} csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()}, success:function (data) { console.log(data); if(data.user){ location.href='/index' } else { $('.error').text(data.msg).css({'color':'red','margin-left':'10px'}) setTimeout(function () { $('.error').text('') },1000) } } }) }) </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {{ request.user}} <h3>this is my index</h3> </body> </html>
login中验证码模块解耦
生成工具包,工具包里面生成一个py文件
get_valid_Code_img()
def get_valid_Code_img(request): # 方式四 import random,string def get_random_color(): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) from PIL import Image, ImageDraw, ImageFont from io import BytesIO img = Image.new('RGB', (270, 34), color=get_random_color()) # 画笔 draw draw = ImageDraw.Draw(img) kumo_font = ImageFont.truetype('static/font/kumo.ttf', size=32) code = '' valid_code_str = '' for i in range(5): random_num = random.randint(0, 9) random_low_alpha = chr(random.randint(65, 90)) random_upper_alpha = chr(random.randint(97, 122)) add = random.choice([random_num, random_low_alpha, random_upper_alpha]) # add2=random.choice(string.ascii_letters+string.digits) # code = ''.join([code,str(add)]) draw.text((i * 50 + 20, 5), str(add), get_random_color(), font=kumo_font) # 画文字 # 保存验证码字符串 valid_code_str += str(add) # draw.line()#画线 # draw.point()#画点 # 补充噪点噪线 防止机器识别 # 噪线 width, height = 210, 35 for i in range(2): x1 = random.randint(0, width) x2 = random.randint(0, width) y1 = random.randint(0, width) y2 = random.randint(0, width) draw.line((x1, y1, x2, y2), fill=get_random_color()) # 噪点 for i in range(50): draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color()) x = random.randint(0, width) y = random.randint(0, height) draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color()) print(valid_code_str) # 生成的字符串---验证码 valid_code_str request.session['valid_code_str'] = valid_code_str ''' 1 assdd 2 COOKIE {'sessionid':assdd } session-key session-data ''' f = BytesIO() img.save(f, 'png') data = f.getvalue() return data
实现一个滑动验证码
一点提交出现滑动验证码,滑动验证码成功再去验证用户名和密码
如果滑动不成功,反复出现要提交
geetest
悟已往之不谏,知来者之可追。