图形验证码
# 图形验证码 def get_valid_code_img(request): import random def get_random_color(): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) from PIL import Image, ImageDraw, ImageFont img = Image.new('RGB', (270, 40), 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_upper_alpha = chr(random.randint(65, 90)) random_char = random.choice([random_num, random_low_alpha, random_upper_alpha]) draw.text((i * 40 + 40, 5), random_char, fill=get_random_color(), font=kumo_font) valid_code_str += random_char # 保存验证码 request.session['valid_code_str']=valid_code_str # 添加噪点噪线 # 添加噪点噪线 width = 270 height = 40 for i in range(3): 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(100): 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 + 2, y + 2), 0, 90, fill=get_random_color()) # 画圆 from io import BytesIO f = BytesIO() # 临时保存在内存 img.save(f, 'png') data = f.getvalue() return HttpResponse(data)
这里保存验证码一定要用session。在验证的时候,如果想通过将验证码声明为全局变量是错误的,因为当有其他用户访问服务器是会改变这个值的。
验证
from django.shortcuts import render, HttpResponse, redirect from django.contrib import auth from django.contrib.auth.models import User from django.http import JsonResponse # Create your views here. def login(request): if request.is_ajax(): user=request.POST.get('user') pwd=request.POST.get('pwd') valid_code_str = request.POST.get('valid_code_str') response={'user':None,'msg':None} if valid_code_str.upper()==request.session.get('valid_code_str').upper(): # 使输入不区分大小写 user_obj=auth.authenticate(username=user,password=pwd) # auth验证 if user_obj: auth.login(request,user_obj) # request.user对象生成 response['user']=user_obj.username else: response['msg']='用户名或密码错误' else: response['msg']='验证码错误' return JsonResponse(response) # 直接返回序列化格式数据,在前端也不需要反序列化 return render(request, 'login.html')
模板
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form >
{% csrf_token %}
<div class="form-group">
<label for="">用户名label>
<input type="text" id="user" class="form-control">
div>
<div class="form-group">
<label for="">密码label>
<input type="password" id="pwd" class="form-control">
div>
<div class="row">
<div class="col-md-6">
<input type="text" class="form-control" id="valid_code">
div>
<div class="col-md-6">
<img id="valid_code_img" width="270" height="40" src="/get_valid_code_img/" alt="图形验证码">
div>
div>
<input type="button" class="btn btn-success" id="submit" value="登录"><span id="error">span>
<a href="/reg/" class="btn btn-info pull-right">注册a>
form>
div>
div>
div>
<script src="/static/jquery-3.3.1.js">script>
<script>
$('#valid_code_img').click(function () {
$(this)[0].src+='?'; //验证码刷新
});
$('#submit').click(function () {
$.ajax({
url:'',
type:'post',
data:{
user:$('#user').val(),
pwd:$('#pwd').val(),
valid_code_str:$('#valid_code').val(),
csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()
},
success:function (data) {
if(data.user){
location.href='/index/'; //跳转页面
}else{
$('#error').text(data.msg).css({'color':'red','margin-left':'10px'});//显示错误信息
setTimeout(function(){
$('#error').text(''); //清空
},1000) //一秒后消失
}
}
}) ;
});
script>
body>
html>