python web Framework Flask-Dynamic Renewal of Graphic Verification Code and Verification Code

The following codes are all described in their own project examples, with little relevant text, mainly in the code annotations.

Self-made Graphic Verification Code

The graphics verification codes mentioned here are all self-made graphics, drawn by the color of canvas, brush and brush font. It is better to encapsulate the validation code into a class. There are absolutely detailed comments in the code. Of course, you can copy them directly.

The fonts involved are all from the system computer, you can directly copy the current directory.

home directory/utils/captcha/__init__.py

import random
import string

# Image:A canvas
# ImageDraw:A paintbrush
# ImageFont:The font of the brush
from PIL import Image, ImageDraw, ImageFont


# Captcha Verification Code
class Captcha(object):
    # Generating 4-digit authentication code
    numbers = 4
    # Width and Height of Verification Code Pictures
    size = (100, 30)
    # Verification code font size
    fontsize = 25
    # Number of interference lines added
    line_number = 2

    # Constructing a Verification Code Source Text
    SOURCE = list(string.ascii_letters)
    for index in range(0, 10):
        SOURCE.append(str(index))

    # Used to draw interference lines
    @classmethod
    def __gene_line(cls, 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=cls.__gene_random_color(), width=2)

    # Used to plot interference points
    @classmethod
    def __gene_points(cls, draw, point_chance, width, height):
        # The size limit is in [0, 100].
        chance = min(100, max(0, int(point_chance)))
        for w in range(width):
            for h in range(height):
                tmp = random.randint(0, 100)
                if tmp > 100 - chance:
                    draw.point((w, h), fill=cls.__gene_random_color())

    # Generating Random Colors
    @classmethod
    def __gene_random_color(cls, start=0, end=255):
        random.seed()
        return (random.randint(start, end),
                random.randint(start, end),
                random.randint(start, end))

    # Random selection of a font
    @classmethod
    def __gene_random_font(cls):
        fonts = [
            "PAPYRUS.TTF",
            "CENTAUR.TTF",
            "Inkfree.ttf",
            "verdana.ttf",
        ]
        font = random.choice(fonts)
        return "utils/captcha/"+font

    # Used to randomly generate a string (including English and numbers)
    @classmethod
    def gene_text(cls, numbers):
        # numbers Is the number of digits that generate the authentication code
        return " ".join(random.sample(cls.SOURCE, numbers))

    # Generating Verification Code
    @classmethod
    def gene_graph_captcha(cls):
        # Width and Height of Verification Code Picture
        width, height = cls.size
        # create picture
        image = Image.new("RGBA", (width, height), cls.__gene_random_color(0, 100))
        # Verification Code Font
        font = ImageFont.truetype(cls.__gene_random_font(), cls.fontsize)
        # Create brush
        draw = ImageDraw.Draw(image)
        # Generate strings
        text = cls.gene_text(cls.numbers)
        # Get font size
        font_width, font_height = font.getsize(text)
        # Fill in strings
        draw.text(((width-font_width)/2, (height-font_height)/2),
                  text, font=font, fill=cls.__gene_random_color(150, 255))
        # Drawing interference lines
        for x in range(0, cls.line_number):
            cls.__gene_line(draw, width, height)
        # Drawing interference points
        cls.__gene_points(draw, 10, width, height)
        with open("captcha.png", "wb") as fp:
            image.save(fp)
        return text, image

Display Graphics Verification Code

General graphics authentication codes are in forms, so that data and suggestions for a short time are stored in redis cache (users click on dynamic refresh of graphics authentication codes). First, we draw the graphic verification code and save it in the project directory (the entry file is the main directory (project directory) app.py file, and the pictures are also saved in the main directory), then access the self-made graphic verification code through the url address (here I only add the main code)

home directory/common/views.py

@bp.route("/captcha")
def graph_captcha():
    """
    //Use the defined graphic validation code class to make the validation code
    //Validation codes are stored in redis caches with validation codes as keys and validation codes as values (ignoring case and case for user experience)
    //Save and access pictures through BytesIO byte stream
    :return: Picture response
    """
    # Get the authentication code
    text, image = Captcha.gene_graph_captcha()
    cpcache.set(text.lower(), text.lower())

    # BytesIO:Byte stream
    out = BytesIO()
    # Save pictures
    image.save(out, "png")
    # After storing the picture, point the pointer of the file to the file header, so that the next saved picture can cover the previously saved picture, saving space.
    out.seek(0)
    # Visit the picture and return it to the front desk as a response
    resp = make_response(out.read())
    resp.content_type = "image/png"
    return resp

The code for the front-end page is as follows:

<div class="form-group">
    <div class="input-group">
        <input type="text" class="form-control" name="graph_captcha" placeholder="Graphic Verification Code">
        <span class="input-group-addon captcha-addon">
            <img id="captcha-img" class="captcha-img" src="{{ url_for("common.graph_captcha") }}" alt="">
        </span>
    </div>
</div>

Dynamic refresh verification code

It's all about regenerating a graphics verification code and accessing it again through the url, but it's very cumbersome, and it's hard for me to explain here (hard!!!). Let's copy the code directly. This code is to click on the image to generate a new URL to access the image.

This file can be placed in a public directory.

var cpparam = {
    setParam: function(href, key, value){
        //Reload the entire page
        var isReplaced = false;
        var urlArray = href.split("?");
        if(urlArray.length > 1){
            var queryArray = urlArray[1].split("&");
            for(var i=0; i < queryArray.length; i++){
                var paramArray = queryArray[i].split("=");
                if(paramArray[0] == key){
                    paramArray[1] = value;
                    queryArray[i] = paramArray.join("=");
                    isReplaced = true;
                    break;
                }
            }
            if(!isReplaced){
                var params = {};
                params[key] = value;
                if(urlArray.length > 1){
                    href = href + "$" + $.param(params);
                }else{
                    href = href + "?" + $.param(params);
                }
            }else{
                var params = queryArray.join("&");
                urlArray[1] = params;
                href = urlArray.join("?");
            }
        }else{
            var param = {};
            param[key] = value;
            if(urlArray.length > 1){
                href = href + "$" + $.param(param);
            }else{
                href = href + "?" + $.param(param);
            }
        }
        return href;
    }
};

js files corresponding to html need to implement elements (pictures) click refresh pictures, call the variable cpparam above to generate a chapter of pictures and access them.

$(function(){
   $("#captcha-img").on("click", function(){
       var self = $(this);
       var src = self.attr("src");
       var newsrc = cpparam.setParam(src, "xx", Math.random());
       self.attr("src", newsrc);
   });
});

Keywords: Python Redis

Added by thinguy on Sun, 13 Oct 2019 21:42:22 +0300