from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
from PIL import ImageFilter
import random
import math
import string
import os
BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
class CreateCheckCode:
#生成几位数的验证码
number = 4
#生成验证码图片的高度和宽度
size = (100,30)
#背景颜色,默认为白色
bg_color = (255,255,255)
#字体颜色,默认为蓝色
font_color = (0,0,255)
#干扰线颜色。默认为红色
line_color = (255,0,0)
#是否要加入干扰线
draw_line = True
#加入干扰线条数的上下限
line_number = (1,5)
#字体路径和保存路径
font_path = os.path.join(BASE_PATH, 'static/font/Monaco.ttf')
save_path = os.path.join(BASE_PATH, 'static/img/check_code')
def create_str(self):
'''生成字符串:字母+数字'''
source = list(string.ascii_letters)
for index in range(0, 10):
source.append(str(index))
return ''.join(random.sample(source, self.number))
def create_lines(self,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=self.line_color)
def check_code(self, filename):
width, height = self.size
image = Image.new('RGBA', self.size, self.bg_color) # 创建空白图片
font = ImageFont.truetype(self.font_path, 25) # 验证码的字体和字体大小
draw = ImageDraw.Draw(image) # 创建画笔
text = self.create_str() # 生成字符串
# print('字符串:',text)
font_width, font_height = font.getsize(text)
# 填充字符串
draw.text(((width - font_width)/self.number,(height-font_height)/self.number),text,font=font,fill=self.font_color)
if self.draw_line:
self.create_lines(draw, width, height)
self.create_lines(draw, width, height)
self.create_lines(draw, width, height)
# 创建扭曲
image = image.transform((width + 20, height + 10), Image.AFFINE, (1, -0.3, 0, -0.1, 1, 0), Image.BILINEAR)
# 滤镜,边界加强
image = image.filter(ImageFilter.EDGE_ENHANCE_MORE)
# 保存验证码图片.png
image.save('%s/%s.png' % (self.save_path, filename))
# print("图片保存路径:", self.save_path)
return text
from utils.check_code import CreateCheckCode
import uuid
def check_code(request):
'''生成验证码图片'''
check_obj = CreateCheckCode()
nid = str(uuid.uuid4())
text = check_obj.check_code(nid)
file_path = os.path.join('static/img/check_code','%s.png'%nid)
f = open(file_path,'rb')
data = f.read()
f.close()
request.session['check_code'] = text
# 返回一个验证码图片到前端显示出来
return HttpResponse(data)
def login(request):
'''登陆'''
if request.method == 'GET':
return render(request, 'login.html')
if request.method == 'POST':
result = {'status':False,'msg':None}
name = request.POST.get('username')
pwd = request.POST.get('password')
ck_code = request.POST.get('check_code') # 用户输入的验证码
ss_code = request.session['check_code'] # 页面生成的验证码
user_obj = UserInfo.objects.filter(username=name).first()
blog_obj = Blog.objects.filter(user_id=user_obj.id).first()
# print('****************',theme_id.theme)
if user_obj.username == name and user_obj.pwd == md5(pwd):
if ck_code.lower() == ss_code.lower():
request.session['user_id'] = user_obj.id
request.session['username'] = name
request.session['is_login']=True
request.session['theme_id']=blog_obj.theme
request.session['suffix']=blog_obj.suffix
request.session['title']=blog_obj.title
if request.POST.get("one-month"):
request.session.set_expiry(60*60*24*30)
print('登陆成功')
return redirect('http://127.0.0.1:8000')
else:
result['status'] = True
result['msg'] = '验证码错误或过期'
return render(request, 'login.html',{'result':result})
else:
result['msg'] = '用户名或密码错误'
return render(request, 'login.html', {'result':result})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% load staticfiles %}
<link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.css' %}"/>
<link rel="stylesheet" href="{% static 'css/account_styles.css' %}"/>
<style>
.login-button{
background-color: #4b90ef;
margin-top:20px;
}
</style>
</head>
<body class="bg-color">
<div class="register-band" style="height: 470px;">
<div class="content-band">
<form action="/login.html" method="POST" novalidate>
{% csrf_token %}
<div class="login-title">欢迎登陆</div>
<div class="login-text">用户名</div>
<div>
<input type="text" class="form-control" name="username" placeholder="用户名">
</div>
<div class="login-text">密码</div>
<div>
<input type="password" class="form-control" name="password" placeholder="密码">
</div>
<div class="check-code-band">
<input type="text" class="form-control" name="check_code" placeholder="验证码">
<!--访问生成验证码的URL,触发check_code函数-->
<img src="/check_code.html" onclick="changeImg(this);"/>
</div>
<div style="margin-top: 15px;"><input type="checkbox" name="one-month"/>一个月内免登陆</div>
<div style="margin-top: 15px;color: red;">{{ result.msg }}</div>
<div style="text-align: center;"><input type="submit" value="登陆" class="register-button login-button"/></div>
</form>
</div>
</div>
<script>
function changeImg(ths) {
// src里面加上?就会再发一次请求,验证码就会刷新一次
ths.src = ths.src + '?';
}
</script>
</body>
</html>