1.图形验证码
- 使用Django生成登录图形验证码,并且存入缓存中;
- 前端点击图片触发验证码生成,前端验证码输入,通过ajax与后端数据交互;
- 后端接收前端传递验证码,到缓存查找如果找到以及验证码一致通过验证
验证码生成逻辑
- 生成随机字符串
- 不同字体
- 生成干扰线,防止机器采集识别绕过验证码
- 画布、画笔
- 生成返回字符串图片
1.1 配置Django缓存
- settings配置文件,设置Redis作为图片验证码缓存
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://192.168.3.251:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient"
}
}
}
1.2 生成图形验证码
- 废话不说了,直接上代码,返回值文本 图片 两种类型
- 修改验证码数量;画布大小;字体大小,修改Captcha类属性
import random
import string
from PIL import Image, ImageDraw, ImageFont
class Captcha(object):
number = 5
size = (100,40)
fontsize = 25
line_number = 2
SOURCE = list(string.ascii_letters)
for index in range(0, 10):
SOURCE.append(str(index))
@classmethod
def __gene_line(cls,draw,width,height):
begin = (random.randint(0, width), random.randint(0, height))
end = (random.randint(0, width), random.randint(0, height))
draw.line([begin, end], fill = cls.__gene_random_color(),width=2)
@classmethod
def __gene_points(cls,draw,point_chance,width,height):
chance = min(100, max(0, int(point_chance)))
for w in range(width):
for h in range(height):
tmp = random.randint(0, 100)
if tmp > 100 - chance:
draw.point((w, h), fill=cls.__gene_random_color())
@classmethod
def __gene_random_color(cls, start=0, end=255):
random.seed()
return (random.randint(start,end), random.randint(start,end), random.randint(start,end))
@classmethod
def __gene_random_font(cls):
fonts = [
'Courgette-Regular.ttf',
'LHANDW.TTF',
'Lobster-Regular.ttf',
'verdana.ttf'
]
font = random.choice(fonts)
return 'utils/captcha/'+font
@classmethod
def gene_text(cls, number):
return ''.join(random.sample(cls.SOURCE, number))
@classmethod
def gene_graph_captcha(cls):
width, height = cls.size
image = Image.new('RGBA', (width, height), cls.__gene_random_color(0, 100))
font = ImageFont.truetype(cls.__gene_random_font(), cls.fontsize)
draw = ImageDraw.Draw(image)
text = cls.gene_text(cls.number)
font_width, font_height = font.getsize(text)
draw.text(((width - font_width) / 2, (height - font_height) / 2),text,font= font,fill=cls.__gene_random_color(150, 255))
for x in range(0, cls.line_number):
cls.__gene_line(draw, width, height)
cls.__gene_points(draw, 10, width, height)
return (text, image)
1.3 Django视图写入逻辑代码
- 图片是一个流数据,也就是存到一个管道中,不像字符串用容器保存,
- 需要使用IO模块BytesIO:from io import BytesIO
def image_captcha(request):
text, image = Captcha.gene_graph_captcha()
out = BytesIO()
image.save(out, 'png')
out.seek(0)
response = HttpResponse(content_type='image/png')
response.write(out.read())
response['Content-length'] = out.tell()
cache.set(text.lower(), text.lower(), 5*60)
return response
from django.urls import path
from . import views
app_name = 'cmsauth'
urlpatterns = [
...
path('image_captcha/', views.image_captcha, name='image_captcha'),
...
]
1.4 前端界面配置
- 前端生成图形验证码地方,使用url反向解析 {% url ‘cmsauth:image_captcha’ %}
<div class="input-group">
<div class="short-input-group">
<input type="text" class="form-control" name="img_captcha" placeholder="图形验证码">
</div>
<div class="input-group-addon">
<img src="{% url 'cmsauth:image_captcha' %}" alt="" class="img-captcha" style="cursor:pointer;">
</div>
</div>
qfajax.post({
'url':'/account/register/',
'data':{
'telephone':telephone,
'username':username,
'image_captcha':imageCaptcha,
'password1':password1,
'password2':password2,
},
//result存放服务器返回的结果
'success':function (result) {
alert(result.code)
}
})
1.5 效果图