validCode.py
import random from io import BytesIO from PIL import Image, ImageDraw, ImageFont def get_random_color(): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) def get_valid_code_img(request): img = Image.new('RGB', (260, 34), color=get_random_color()) draw = ImageDraw.Draw(img) kumo_font = ImageFont.truetype('static/font/kumo.ttf', size=28) valid_code_str = '' for i in range(5): random_num = str(random.randint(0, 9)) random_low_alpha = chr(random.randint(97, 122)) random_high_alpha = chr(random.randint(65, 90)) random_char = random.choice([random_num, random_low_alpha, random_high_alpha]) draw.text((i * 50 + 20, 5), random_char, get_random_color(), font=kumo_font) # 保存验证码字符串 valid_code_str += random_char # 噪点噪线 width = 260 height = 34 for i in range(5): x1 = random.randint(0, width) x2 = random.randint(0, width) y1 = random.randint(0, height) y2 = random.randint(0, height) draw.line((x1, y1, x2, y2), fill=get_random_color()) for i in range(5): draw.point([random.randint(0, width), random.randint(0, height)], fill=get_random_color()) x = random.randint(0, width) y = random.randint(0, height) draw.arc((x, y, x + 4, y + 4), 0, 90, fill=get_random_color()) # 保存验证码字符串到该用户的session request.session['valid_code_str'] = valid_code_str f = BytesIO() # 用完之后,BytesIO会自动清掉 img.save(f, 'png') data = f.getvalue() return data
views.py
from django.contrib import auth from django.shortcuts import render, HttpResponse from django.http import JsonResponse from blog.utils.validCode import get_valid_code_img def get_validCode_img(request): """ 基于PIL模块动态生成响应状态码图片 :param request: :return: """ data = get_valid_code_img(request) return HttpResponse(data) def login(request): if request.method == 'POST': response = {'user': None, 'msg': None} user = request.POST.get('user') pwd = request.POST.get('pwd') valid_code = request.POST.get('valid_code') valid_code_str = request.session.get('valid_code_str') if valid_code.lower() == valid_code_str.lower(): user = auth.authenticate(username=user, password=pwd) if user: auth.login(request, user) # request.user == 当前登录对象 response['user'] = user.username else: response['msg'] = '用户名或密码错误' else: response['msg'] = '验证码错误' return JsonResponse(response) return render(request, 'login.html')
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登陆页面</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> </head> <body> <h3>登陆页面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <form id="fm"> {% csrf_token %} <div class="form-group"> <label for="id_user">用户名</label> <input type="text" name="user" id="id_user" class="form-control"> </div> <div class="form-group"> <label for="id_pwd">密码</label> <input type="text" name="pwd" id="id_pwd" class="form-control"> </div> <div class="form-group"> <label for="id_valid_code">验证码</label> <div class="row"> <div class="col-md-6"> <input type="text" name="valid_code" id="id_valid_code" class="form-control"> </div> <div class="col-md-6"> <img width="260" height="34" src="/get_validCode_img/" id="valid_code_img"> </div> </div> </div> <input type="button" value="提交" id="login_btn" class="btn btn-default "> <span id="error"></span> </form> </div> </div> </div> <script src="/static/blog/js/jquery-3.3.1.js"></script> <script> // 验证码图片刷新 $('#valid_code_img').click(function () { $(this)[0].src += '?'; // 问号的唯一意义是:图片链接发生了变化,图片需要刷新 }); // 登陆验证 $('#login_btn').click(function () { $.ajax({ url: '', type: 'post', data: $('#fm').serialize(), success: function (data) { if (data.user) { location.href = '/index/' } else { $('#error').text(data.msg).css({'color': 'red', 'margin-left': '10px'}); setTimeout(function () { $('#error').text('') // 3秒后清空error信息 }, 3000) } } }) }) </script> </body> </html>