现在基本的网站登录都有验证码,那么在django中实现也可以实现登录验证码。需要知道具体的原理,首先用户访问login页面,我们在服务器创建一个白板图片并添加随机字符串验证码返回给用户,Session存在随机字符串;用户发送post数据提交的时候,核对用户输入的随机字符串是否跟Session中的一致。
首先考虑,生成的图片放在哪。如果放在文件中,需要知道图片的路径才能在页面上显示,也可以放在内存中。很显然不能存在文件中,因为图片验证码是动态生成的,所以放在文件中不合适。
难点就是验证码的生成,这里我们创建一个check_code.py文件来编写验证码图片的代码,主要用的就是pil模块,内容也不多,注释为了更加直观,我就直接写在了后面:
from PIL import Image,ImageDraw,ImageFont,ImageFilter
import random
_letter_cases="abcdefghjkmnpqrstuvwxyz" #小写字母 取出干扰字母i,l,o
_upper_cases=_letter_cases.upper() #大写字母
_numbers=''.join(map(str,range(3,10))) #数字
init_chars=''.join( (_letter_cases,_upper_cases,_numbers) )
def create_validate_code(
size=(120,30), #图片的大小,格式(宽,高),默认为(120,30)
chars=init_chars, #允许的字符集合
img_type='GIF', #图片保存的格式,默认为为GIF,可选GIF,JPEG,JPG,PNG
mode='RGB', #图片格式,默认为RGB
bg_color=(255,255,255), #背景颜色,默认为白色
fg_color=(0,0,255), #前景色,验证码字符串颜色,默认为蓝色#0000FF
font_size=18, #验证码字体大小
font_type='JIANTI.ttf', #验证码字体
length=4, #验证码字符格式
draw_lines=True, #是否画干扰线
n_line=(1,2), #干扰线的条数范围,格式元组,默认为(1,2),只有draw_lines为True时有效
draw_polints=True, #是否画面干扰
polint_chance=2, #干扰点出现的概率,大小范围[0,100]
):
width,height=size #宽高
#创建图形
img=Image.new(mode,size,bg_color)
draw=ImageDraw.Draw(img) #创建画笔
def get_chars():
#生成给定长度的字符串,返回列表格式
return random.sample(chars,length)
def create_lines():
#绘制干扰线
line_num=random.randint(*n_line) #干扰线条数
for i in range(line_num):
#起始点
begin=(random.randint(0,size[0]),random.randint(0,size[1]))
#结束点
end=(random.randint(0,size[0]),random.randint(0,size[1]))
draw.line([begin,end],fill=(0,0,0))
def create_polints():
#绘制干扰点
chance=min(100,max(0,int(polint_chance))) #大小限制在[0,100]
for w in range(width):
for h in range(height):
tap=random.randint(0,100)
if tap>100-chance:
draw.point((w,h),fill=(0,0,0))
def create_strs():
#绘制验证码字符
c_chars=get_chars()
strs='%s'% ' '.join(c_chars) #每个字符前后以空格隔开
font=ImageFont.truetype(font_type,font_size)
font_width,font_heigth=font.getsize(strs)
draw.text( (width-font_width-30,height-font_heigth-10 ),
strs,font=font,fill=fg_color)
return strs
if draw_lines:create_lines() #先画干扰线
if draw_polints:create_polints()
strs=create_strs()
#图形扭曲参数
params=[1-float(random.randint(1,2)) /100,
0,0,0,
1-float(random.randint(1,10)) /100,
float(random.randint(1,2)) / 500,
0.001,
float(random.randint(1,2)) /500]
img=img.transform(size,Image.PERSPECTIVE,params) #创建扭曲
img=img.filter(ImageFilter.EDGE_ENHANCE_MORE) #滤镜,边界加强(阈值更大)
#img图片对象 验证码字符串
return img,strs.replace(" ","")
以上代码返回一个验证码图片用于展示在页面中和验证字符串用于核对,验证码图片可以存放在内存中,并且在页面可以刷新验证码:
views视图函数
from check_code import create_validate_code
def login(request):
if request.method=='GET':
return render(request,'login.html')
if request.method=='POST':
user_strs=request.POST.get('check_code').upper()
check_code=request.session['CheckCode'].upper()
if user_strs==check_code:
return render(request,'index.html')
else:
return render(request,'login.html')
from io import BytesIO
def check_code(request):
# 1.创建一张图片 pip3 install Pillow
# 2.在图片中写入随机字符串
# 3.将图片写入到指定文件
# 4.打开指定目录文件,读取内容
stream=BytesIO() #字节的io操作 打开一个文件
img,code=create_validate_code()
img.save(stream,'PNG')
request.session['CheckCode']=code #写入到session中
return HttpResponse(stream.getvalue()) #读取内存中的内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录管理</title>
<link href="/static/css/login.css" rel="stylesheet">
</head>
<body>
<div id="login">
<form action="" method="post">
<strong class="login-title">用户登录</strong>
<p><input type="username" name="user" id="user" placeholder="用户名"></p>
<p><input type="password" name="passw0rd" id="pwd" placeholder="密码"></p>
<p><input type="text" name="check_code" id="yzm" placeholder="验证码"></p>
<p><图片标签img src="/check_code.html/" onclick="changeCheck(this);"></p>
<p><input type="submit" id="submit" value="登录"></p>
</form>
</div>
<div style="text-align:center;">
</div>
<script>
function changeCheck(ths) {
ths.src=ths.src+"?"; //改变图片的url地址,让图片刷新
}
</script>
</body>
</html>
login.html页面的img标签是后台自动添加的,主要就是src属性和绑定的时间,用户点击的是后更改图片的url地址,让图片验证码可以刷新,具体的效果如图:

声明:1. 本站所有资源来源于用户上传和网络,因此不包含技术服务请大家谅解!如有侵权请邮件联系客服!
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!
2. 本站不保证所提供下载的资源的准确性、安全性和完整性,资源仅供下载学习之用!如有链接无法下载、失效或广告,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!