Spring Boot tutorial (9): verification code function kaptcha

I often see the logical design of the verification code when surfing the Internet daily. For example, when logging in to the account, posting on the forum, and purchasing goods, the website will require the user to enter the verification code before the actual operation, and the generation rules or display forms of the verification code are also different. , But this design does already exist in major websites, the following is its definition in Baidu Encyclopedia:

CAPTCHA is the abbreviation of "Completely Automated Public Turing test to tell Computers and Humans Apart", which is a public automatic program that distinguishes whether a user is a computer or a human. Can prevent: maliciously cracking passwords, swiping tickets, and forum watering, effectively preventing a certain registered user from using a specific program to brute force the continuous login attempts of a certain registered user. In fact, using verification codes is a common way for many websites. We use A relatively simple way to achieve this function. This question can be generated and judged by a computer, but only humans can answer it. Since computers cannot answer CAPTCHA questions, the user who answers the question can be considered human.

1. General steps

1. Import dependencies

<!-- 验证码 -->
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>

2. Configuration class

Create KaptchaConfig class under com.wang.config:

package com.wang.config;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import com.google.code.kaptcha.util.Config;

import java.util.Properties;

@Component
public class KaptchaConfig {
    
    
    @Bean
    public DefaultKaptcha getDefaultKaptcha(){
    
    
        com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha = new com.google.code.kaptcha.impl.DefaultKaptcha();
        Properties properties = new Properties();
        // 图片边框
        properties.put("kaptcha.border", "no");
        // 字体颜色
        properties.put("kaptcha.textproducer.font.color", "black");
        // 图片宽
        properties.put("kaptcha.image.width", "160");
        // 图片高
        properties.put("kaptcha.image.height", "40");
        // 字体大小
        properties.put("kaptcha.textproducer.font.size", "30");
        // 验证码长度
        properties.put("kaptcha.textproducer.char.space", "5");
        // 字体
        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

Here is the rule configuration for the generated image verification code, such as color, width, height, length, font, etc. You can modify these rules according to your needs, and then you can generate the verification code you want.

3. Back-end processing

Create a new KaptchaController in the controller package, and then inject the DefaultKaptcha class that has just been configured, and then you can create a new method in which you can generate a verification code object and write it to the front end as a picture stream for display. The code is as follows:

package com.wang.controller;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;

@Controller
public class KaptchaController {
    
    
    @Autowired
    private DefaultKaptcha captchaProducer;

    @GetMapping("/kaptcha")
    public void defaultKaptcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
        byte[] captchaOutputStream;
        ByteArrayOutputStream imgOutputStream = new ByteArrayOutputStream();
        try {
    
    
            //生产验证码字符串并保存到session中
            String verifyCode = captchaProducer.createText();
            httpServletRequest.getSession().setAttribute("verifyCode", verifyCode);
            BufferedImage challenge = captchaProducer.createImage(verifyCode);
            ImageIO.write(challenge, "jpg", imgOutputStream);
        } catch (IllegalArgumentException e) {
    
    
            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        captchaOutputStream = imgOutputStream.toByteArray();
        httpServletResponse.setHeader("Cache-Control", "no-store");
        httpServletResponse.setHeader("Pragma", "no-cache");
        httpServletResponse.setDateHeader("Expires", 0);
        httpServletResponse.setContentType("image/jpeg");
        ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream();
        responseOutputStream.write(captchaOutputStream);
        responseOutputStream.flush();
        responseOutputStream.close();
    }
}

We added the defaultKaptcha method to the controller. The path intercepted by this method is /kaptcha. After accessing the path in the front end, a picture stream can be received and displayed on the browser page.

4. Front-end processing

Create a new kaptcha.html, display the verification code on this page, the code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>验证码显示</title>
</head>
<body>
<img src="/kaptcha" onclick="this.src='/kaptcha?d='+new Date()*1" />
</body>
</html>

Access the back-end verification code path /kaptcha, and return it to display in the img tag. After that, the onclick method is defined. When the img tag is clicked, a new verification code can be dynamically switched to display. The access path is /kaptcha when clicked. ?d=1565950414611, that is, there is a timestamp parameter behind the original verification code path. The timestamp will change, so each click will be a different request from the previous one. If you don’t handle it this way, due to the browser’s mechanism The request may not be resent.

Finally, start the project service and test the service in the browser:

Insert picture description here

Two, verification code input verification

After the verification code is displayed, the next thing we need to do is to compare and verify the verification code entered by the user, because the general approach is to save the currently generated verification code after the backend is generated (maybe in the session, Or in the cache or in the database), and then displayed on the front-end page. After seeing the verification code, the user fills in the verification code in the corresponding input box of the page, and then sends the request to the back-end, and the back-end will respond to the request after receiving the request. The verification code entered by the user is verified. If it is incorrect, no follow-up operation will be performed. Next, let's briefly implement this process.

1. Back-end processing

Add a verify method to the KaptchaController class, the code is as follows:

@GetMapping("/verify")
    @ResponseBody
    public String verify(@RequestParam("code") String code, HttpSession session) {
    
    
        if (StringUtils.isEmpty(code)) {
    
    
            return "验证码不能为空";
        }
        String kaptchaCode = session.getAttribute("verifyCode") + "";
        if (StringUtils.isEmpty(kaptchaCode) || !code.equals(kaptchaCode)) {
    
    
            return "验证码错误";
        }
        return "验证成功";
    }

The path intercepted by this method is /verify, and the request parameter is code, which is the verification code entered by the user. After basic non-empty verification, it is compared with the verifyCode value previously saved in the session. If it is different, a verification code error will be returned. , The same will return verification success.

2. Front-end processing

Create a new verify.html, the verification code is displayed on the page, and there is an input box and a submit button for the user to enter the verification code. A static file jquery.js is required. The code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>验证码测试</title>
</head>
<body>
<img src="/kaptcha" onclick="this.src='/kaptcha?d='+new Date()*1" />
<input type="text" maxlength="5" id="code" placeholder="请输入验证码" />
<button id="verify">验证</button>
</body>
<script src="../static/js/plugins/jquery/jquery.js"></script>
<script type="text/javascript">
    $(function () {
    
    
        $('#verify').click(function () {
    
    
            var code = $('#code').val();
            $.ajax({
    
    
                type: 'GET', //方法类型
                url: '/verify?code=' + code,
                success: function (result) {
    
    
                    alert(result);
                },
                error: function () {
    
    
                    alert('请求失败');
                },
            });
        });
    });
</script>
</html>

After the user enters the verification code in the input box, click the "Verify" button. After the event is triggered, the js method will be executed. This method will get the value of the verification code entered by the user and use it as a request parameter, and then make an Ajax request. Then, the processing result returned by the backend will be displayed in the pop-up box.

Guess you like

Origin blog.csdn.net/Tracycoder/article/details/113986893