环境:win10(64位)+pycharm2018+pillow5.4+python3.7
对Django的跨站请求保护的有所了解的同学会知道{%csrf_token%}在实际上作用并不是那么大,只要我们拿到了cookie的值添加进去就可以避开这种保护机制,所有有了更安全的-------验证码
python实现验证码功能有赖于第三方库Pillow,可以通过它来绘制图像,添加颜色文字并呈现在我们的web网站上。下面是pillow的官方文档:https://pillow.readthedocs.io/en/latest/handbook/index.html
言归正传:实现验证码功能依靠pillow的三个类Image,ImageDraw,ImageFont,分别用于创建画布,画笔,字体。
其中有坑的地方。。。
1:font字体的定义要自己去看自己的电脑支持什么(window的字体在 C:\Windows\Fonts 下)ubuntu在/usr/share/fonts,自己去看支持什么就写什么,不要乱写。
2:ImageDraw.Draw.text()方法,别看官方文档给你那么多参数,,并没有啥用,你只要记住,设置坐标,内容,颜色,字体就万事大吉了
3:在利用内存存储生成的图像时会利用io模块下的StringIO(至少有些教程是这样写的),在这不能用StringIO,因为内存,我们操作的字节,,,所以要用ByteIO方法去保存我们的img
代码如下:
view.py
def varity(request):
from PIL import Image,ImageDraw,ImageFont #导入画布,画题,字体
import random
#背景颜色
bgcolor=(random.randrange(10,160),random.randrange(50,160),255)
#宽高
width = 140
height = 60
#创建画板
img = Image.new(mode='RGB',size=(width,height),color=bgcolor)
#创建画笔
draw = ImageDraw.Draw(img,mode='RGB')
#定义字符
text = 'ABCD1234'
# 字体对象,字体,字号
font1 = ImageFont.truetype('AdobeGothicStd-Bold.otf',40)
#temp用来存储随机生成的验证码
temp = ''
for i in range(4):
# 每循环一次,从a到z中随机生成一个字母或数字
# 65到90为字母的ASCII码,使用chr把生成的ASCII码转换成字符
# str把生成的数字转换成字符串
temp1= text[random.randrange(0,len(text))]
# 把生成的随机码存起来
temp += temp1
#每一次生成新的颜色
color1 = (random.randint(0,255),random.randint(0,255),random.randint(0,255))
#把文字写到img中
draw.text((i*24, i*6),temp1,color1,font1)
#保存到内存流
import io
buf = io.BytesIO()
img.save(buf,'png')
#将验证保存并传递
request.session['code']=temp
#将得到的对象返回
return HttpResponse(buf.getvalue(),'image/png')
def varity1(request):
return render(request,'booktest/varity1.html')
def varity2(request):
name = request.POST['varity']
name1=request.session['code']
if name == name1:
return HttpResponse('ok')
else:
return HttpResponse('error')
urls.py
urls.py
from django.urls import re_path
from .import views
urlpatterns = [
re_path(r'^$',views.index,name='index'),
# re_path(r'^(\d+)$',views.show,name = 'show'),
# re_path(r'^index2$',views.index2),
# re_path(r'^index1',views.index1),
# re_path(r'^user$',views.user),
# re_path(r'^csrf1$',views.csrf1),
# re_path(r'^csrf2$',views.csrf2),
re_path(r'^varity$',views.varity),
re_path(r'^varity1$',views.varity1),
re_path(r'^varity2$',views.varity2),
]
varity1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="varity2" method="post">
{% csrf_token %}
<input type="text" name="varity" value="验证码">
<img src="varity" alt="">
<input type="submit">
</form>
</body>
</html>
运行截图: