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>