You need to generate a dynamic verification code, use it on the login page, and verify it on the front and back ends.

Implementation principle:

The back-end generates dynamic TWO-DIMENSIONAL code and stores it in the session;

The front-end retrieval interface is displayed on the login page.

When the front end logs in, it passes the verification code to the back end, which compares it with the values in the session.

1 Generate a dynamic verification code image

Create a new class ValidateCode:

package hello;

import org.apache.commons.io.FileUtils;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

// Generate a random verification code
public class ValidateCode {
    
    private static Random random = new Random();
    private int width = 160;/ / wide
    private int height = 40;/ / high
    private int lineSize = 30;// The number of interference lines
    private int stringNum = 4;// The number of randomly generated characters
    
    private String randomString = "0123456789abcdefghijklmnopqrstuvwxyz";
    
    private final String sessionKey = "RANDOMKEY";
    
    
    /* * get font */
    private Font getFont(a) {
        return new Font("Times New Roman", Font.ROMAN_BASELINE, 40);
    }
    
    /* * Get the color */
    private static Color getRandomColor(int fc, int bc) {
        
        fc = Math.min(fc, 255);
        bc = Math.min(bc, 255);
        
        int r = fc + random.nextInt(bc - fc - 16);
        int g = fc + random.nextInt(bc - fc - 14);
        int b = fc + random.nextInt(bc - fc - 12);
        
        return new Color(r, g, b);
    }
    
    /* * Draw interference line */
    private void drawLine(Graphics g) {
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(20);
        int yl = random.nextInt(10);
        g.drawLine(x, y, x + xl, y + yl);
    }
    
    /* * Gets a random character */
    private String getRandomString(int num) {
        num = num > 0 ? num : randomString.length();
        return String.valueOf(randomString.charAt(random.nextInt(num)));
    }
    
    /*
     *  绘制字符串
     */
    private String drawString(Graphics g, String randomStr, int i) {
        g.setFont(getFont());
        g.setColor(getRandomColor(108.190));
        System.out.println(random.nextInt(randomString.length()));
        String rand = getRandomString(random.nextInt(randomString.length()));
        randomStr += rand;
        g.translate(random.nextInt(3), random.nextInt(6));
        g.drawString(rand, 40 * i + 10.25);
        return randomStr;
    }
    
    /* * Generate random images */
     public void getRandomCodeImage(HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession();
        // The BufferedImage class is the Image class with a buffer. The Image class is used to describe the Image information
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        Graphics g = image.getGraphics();
        g.fillRect(0.0, width, height);
        g.setColor(getRandomColor(105.189));
        g.setFont(getFont());
        
        // Draw interference lines
        for (int i = 0; i < lineSize; i++) {
            drawLine(g);
        }
        
        // Draw random characters
        String random_string = "";
        for (int i = 0; i < stringNum; i++) {
            random_string = drawString(g, random_string, i);
        }
        
        System.out.println(random_string);
        
        g.dispose();
        
        session.removeAttribute(sessionKey);
        session.setAttribute(sessionKey, random_string);
        
        String base64String = "";
        try {
            // Return the image directly
           ImageIO.write(image, "PNG", response.getOutputStream());   
            
        } catch(Exception e) { e.printStackTrace(); }}}Copy the code

Next write a Controller that provides an interface to the front end:

package hello;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/v1/user")
public class ValidateCodeController {
        
    
    // Generate a captcha image
    @RequestMapping("/getCaptchaImage")
    @ResponseBody
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) {
        
        try {
            
            response.setContentType("image/png");
            response.setHeader("Cache-Control"."no-cache");
            response.setHeader("Expire"."0");
            response.setHeader("Pragma"."no-cache");
            
            ValidateCode validateCode = new ValidateCode();
            
            // Return the image directly
            validateCode.getRandomCodeImage(request, response);
            
        } catch(Exception e) { System.out.println(e); }}}Copy the code

2 Front-end access port

3 The base64 character string is returned

Sometimes we can’t return the image directly, we need to return a JSON data such as:

In this case, we need to convert image to base64;

The specific code is as follows:

Add a method to the previous ValidateCode class:

		/* * Generate a random image, return base64 string */
    public String getRandomCodeBase64(HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession();
        // The BufferedImage class is the Image class with a buffer. The Image class is used to describe the Image information
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        Graphics g = image.getGraphics();
        g.fillRect(0.0, width, height);
        g.setColor(getRandomColor(105.189));
        g.setFont(getFont());
        
        // Draw interference lines
        for (int i = 0; i < lineSize; i++) {
            drawLine(g);
        }
        
        // Draw random characters
        String random_string = "";
        for (int i = 0; i < stringNum; i++) {
            random_string = drawString(g, random_string, i);
        }
        
        System.out.println(random_string);
        
        g.dispose();
        
        session.removeAttribute(sessionKey);
        session.setAttribute(sessionKey, random_string);
        
        String base64String = "";
        try {
            // Return the image directly
            // ImageIO.write(image, "PNG", response.getOutputStream());
            / / return base64
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ImageIO.write(image, "PNG", bos);
            
            byte[] bytes = bos.toByteArray();
            Base64.Encoder encoder = Base64.getEncoder();
            base64String = encoder.encodeToString(bytes);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return base64String;
    }
Copy the code

Add another routing interface to Controller:

// Generate a verification code, return base64
    @RequestMapping("/getCaptchaBase64")
    @ResponseBody
    public Object getCaptchaBase64(HttpServletRequest request, HttpServletResponse response) {
        
        Map result = new HashMap();
        Response response1 = new Response();
        
        try {
            
            response.setContentType("image/png");
            response.setHeader("Cache-Control"."no-cache");
            response.setHeader("Expire"."0");
            response.setHeader("Pragma"."no-cache");
            
            ValidateCode validateCode = new ValidateCode();
            
            // Return the image directly
            // validateCode.getRandomCode(request, response);
            
            / / return base64
            String base64String = validateCode.getRandomCodeBase64(request, response);
            result.put("url"."data:image/png; base64," + base64String);
            result.put("message"."created successfull");
            System.out.println("test=" + result.get("url"));
            response1.setData(0, result);
            
        } catch (Exception e) {
            System.out.println(e);
        }
        
        return response1.getResult();
    }
Copy the code

Call result:

URL
image
URL

3 Verify the verification code

Generation: