django-验证码生成

django 使用PIL生成验证码

python=3.6.8

django=2.1.8

Pillow=7.0.0

redis=3.3.1

工具形式的验证码生成,并存入redis

import random
import io
import redis
from PIL import ImageDraw, ImageFont, Image
from mysite.settings import BASE_DIR


def get_random_color():
    """
    定义随机的字体颜色
    :return:
    """
    R = random.randrange(255)
    G = random.randrange(255)
    B = random.randrange(255)
    return (R, G, B)


# 获取验证码视图
def mycode(image_id):
    # 画布
    img_size = (120, 50)
    # 定义图画对象
    image = Image.new('RGB', img_size, 'white')
    # 定义画笔对象
    draw = ImageDraw.Draw(image, 'RGB')
    # 定义随机字符串
    source = '0123456789'
    # 定义容器
    code_str = ''
    # 定义字体
    my_font = ImageFont.truetype(font="{}\\myutils\\fonts\\SourceCodePro-Bold.ttf".format(BASE_DIR), size=20)

    for i in range(4):
        # 获取随机颜色
        text_color = get_random_color()
        # 获取随机字符串长度下标(index)
        tmp_num = random.randrange(len(source))
        random_str = source[tmp_num]
        code_str += random_str
        # 将字符串添加到画布上
        draw.text((10+30*i, 20), random_str, text_color, font=my_font)
    # 建立缓存区
    buf = io.BytesIO()
    # 建立redis连接
    conn_redis = redis.Redis(host='127.0.0.1', port=6379, db=1)
    # 保存随机码到redis中
    conn_redis.set(image_id, code_str, ex=300)  # ex代表seconds,px代表ms
    # 保存图片
    image.save(buf, 'png')
    return buf.getvalue()

views.py

from django.views import View
from django.http import HttpResponse
from myutils.common import mycode
class RandomImageView(View):
    def get(self, request, image_id):  # 生成的验证码的key值
        return HttpResponse(mycode(image_id), 'image/png')

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('random_image/<str:image_id>/', views.RandomImageView.as_view()),  # 随机生成验证码  ]

vue中Register.vue

<template>
    <div>
        <form >
            <ul>
                <li>
                    <label>用户名:</label>
                    <input type="text" v-model="username" >
                 </li>
                 <li>
                    <label>密&emsp;码:</label>
                    <input type="password" v-model="password" >
                </li>
                <li>
                    <label>验证码:</label>
                    <input type="text" v-model="image_code" class="msg_input" >
                    <img :src="image_code_url + code_cid + '/'" id="msg_code" @click="refresh"  alt="图形验证码" class="pic_code">
                </li>
                <li class="reg_sub">
                    <input type="submit" value="登 陆" name="">
                </li>
            </ul>
        </form>
    </div>
</template>

<script>
export default {
    data() {
        return {
            username: '',
            password: '',
            image_code: '',
            code_cid: '',
            image_code_url: 'http://127.0.0.1:8000/day01/random_image/',
            
        }
    },
    methods: {
        // 生成uuid随机字符串
        generate_uuid() {
            var d = new Date().getTime();
            if (window.performance && typeof window.performance.now === "function") {
                d += performance.now(); //use high-precision timer if available
            }
            var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
                /[xy]/g,
                function(c) {
                var r = (d + Math.random() * 16) % 16 | 0;
                d = Math.floor(d / 16);
                return (c == "x" ? r : (r & 0x3) | 0x8).toString(16);
                }
            );
            return uuid;
        },
        // 点击图片刷新验证码
        refresh(){
            this.code_cid = this.generate_uuid()
        },
    },
    mounted() {  // 页面加载完成以后,生成验证码
        this.code_cid = this.generate_uuid()
    }
}
</script>

CBV形式的验证码(简单)

from django.conf import settings
from django.views import View
from django.http import HttpResponse
import random
import io
import redis
from PIL import ImageDraw, ImageFont, Image


class MyRandomStr(View):
    """
    定义验证码类,用来生成验证码
    """
    # 定义随机颜色
    def get_random_color(self):
        R = random.randrange(255)
        G = random.randrange(255)
        B = random.randrange(255)
        return (R, G, B)

    # 获取验证码视图
    def get(self, request, image_id):
        # 画布
        img_size = (120, 50)
        # 定义图画对象
        image = Image.new('RGB', img_size, 'white')
        # 定义画笔对象
        draw = ImageDraw.Draw(image, 'RGB')
        # 定义随机字符串
        source = '0123456789'
        # 定义容器
        code_str = ''
        # 定义字体
        my_font = ImageFont.truetype(font="{}\\myutils\\fonts\\SourceCodePro-Bold.ttf".format(settings.BASE_DIR), size=15)

        for i in range(4):
            # 获取随机颜色
            text_color = self.get_random_color()
            # 获取随机字符串长度下标(index)
            tmp_num = random.randrange(len(source))
            random_str = source[tmp_num]
            code_str += random_str
            # 将字符串添加到画布上
            draw.text((10+30*i, 20), random_str, text_color, font=my_font)

        # 建立redis连接
        conn_redis = redis.Redis(host='127.0.0.1', port=6379, db=1)
        # 保存随机码到redis中
        conn_redis.set(image_id, code_str, ex=5)  # ex代表seconds,px代表ms

        # 建立缓存区
        buf = io.BytesIO()

        # 保存图片
        image.save(buf, 'png')
        return HttpResponse(buf.getvalue(), 'image/png')

验证码(复杂)

from PIL import Image, ImageDraw, ImageFont
import redis
from verify.settings import FONTS_DIRS
import random
import os
from django.http import HttpResponse
import io

# Create your views here.

def generate_image_code(request, image_id):
    # 图片验证码
    '''
        本地图片验证码生成函数
    '''
    bgcolor = (random.randrange(20, 100), random.randrange(
        20, 100), random.randrange(20, 100))
    width = 110
    height = 40
    # 创建画面对象
    im = Image.new('RGB', (width, height), bgcolor)
    # 创建画笔对象
    draw = ImageDraw.Draw(im)
    # 调用画笔的point()函数绘制噪点
    for i in range(0, 100):
        xy = (random.randrange(0, width), random.randrange(0, height))
        fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
        draw.point(xy, fill=fill)
    # 定义验证码的备选值
    str = '1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm'
    # 随机选取4个值作为验证码
    code_str = ''
    for i in range(0, 4):
        code_str += str[random.randrange(0, len(str))]
    # 构造字体对象

    fonts_files = os.path.join(
        FONTS_DIRS, 'SourceCodePro-Bold.ttf')
    font = ImageFont.truetype(fonts_files, 30)
    # 构造字体颜色
    fontcolor1 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor2 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor3 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor4 = (255, random.randrange(0, 255), random.randrange(0, 255))
    # 绘制4个字
    draw.text((5, 2), code_str[0], font=font, fill=fontcolor1)
    draw.text((25, 2), code_str[1], font=font, fill=fontcolor2)
    draw.text((50, 2), code_str[2], font=font, fill=fontcolor3)
    draw.text((75, 2), code_str[3], font=font, fill=fontcolor4)
    # 释放画笔
    del draw
    # 存入缓存,用于做进一步验证,并设置超时时间为10分组
    print(rand_str)
    # 建立redis连接
    conn_redis = redis.Redis(host='127.0.0.1', port=6379, db=1)
    # 保存随机码到redis中
    conn_redis.set(image_id, code_str, ex=5)  # ex代表seconds,px代表ms
    buf = io.BytesIO()
    # 将图片保存在内存中,文件类型为png
    im.save(buf, 'png')
    # 将内存中的图片数据返回给客户端,MIME类型为图片png!
    return HttpResponse(buf.getvalue(), 'image/png')
posted @ 2020-09-27 18:33  李超呀  阅读(291)  评论(0编辑  收藏  举报