15. Add verification code part to login module

Verification code login process, read by other people’s blogs

Implementation process

  • SSM has actually done it before , saving it in the session , but before it put the value of the verification code in the session , but this time it saved the value of the verification code in redis, and set an expiration time for it, 120 seconds.

  • Introduce redis and Kaptcha dependencies

  • <!--kaptcha依赖-->
    <dependency>
    	<groupId>com.github.axet</groupId>
    	<artifactId>kaptcha</artifactId>
    	<version>0.0.9</version>
    </dependency>
    <!--redis依赖-->
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    

 Configure redis in application.properties

spring.redis.port=6379
spring.redis.host=127.0.0.1
spring.redis.database=0

kaptcha configuration information

package com.cy.store.config;

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

import java.util.Properties;

/**
 * @author ZhangHailong
 * @date 2022/5/18 - 12:23
 * @project_name Kaptcha配置信息
 */
@Configuration
public class KaptchaConfig {

    @Bean
    public DefaultKaptcha getDDefaultKaptcha() {
        DefaultKaptcha dk = new DefaultKaptcha();
        Properties properties = new Properties();
        // 图片边框
        properties.setProperty("kaptcha.border", "yes");
        // 边框颜色
        properties.setProperty("kaptcha.border.color", "105,179,90");
        // 字体颜色
        properties.setProperty("kaptcha.textproducer.font.color", "red");
        // 图片宽
        properties.setProperty("kaptcha.image.width", "110");
        // 图片高
        properties.setProperty("kaptcha.image.height", "40");
        // 字体大小
        properties.setProperty("kaptcha.textproducer.font.size", "30");
        // session key
        properties.setProperty("kaptcha.session.key", "code");
        // 验证码长度
        properties.setProperty("kaptcha.textproducer.char.length", "5");
        // 字体
        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
        Config config = new Config(properties);
        dk.setConfig(config);
        return dk;
    }

}

When the user accesses the login page login.html, after the page is loaded, a request is sent to obtain the verification code image. The processing is: ① The returned image format is base64 encoded, ② The format of the verification code key stored in redis is : CAPTCHA+random number, its value is the actual value of the verification code

package com.cy.store.controller;

import com.cy.store.common.Const;
import com.cy.store.util.JsonResult;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author ZhangHailong
 * @date 2022/5/18 - 12:25
 * @project_name
 */
@RestController
@RequestMapping("kaptcha")
public class KaptchaController extends BaseController{

    @Autowired
    DefaultKaptcha defaultKaptcha;

    @Autowired
    StringRedisTemplate redisTemplate;

    @RequestMapping(value = "getKaptchaImage", method = RequestMethod.GET)
    public JsonResult<Object> getKaptchaImageController(HttpServletResponse httpServletResponse) throws IOException {

        ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
        String codeKey = "";

        try {

            //生产验证码字符串
            String codeValue = defaultKaptcha.createText();

            // 随机生成一个codeKey,用于鉴别验证码身份
            codeKey = Const.CAPTCHA_K + UUID.randomUUID().toString();

            // 将codeKey和codeValue存放到redis中
            redisTemplate.opsForValue().set(codeKey, codeValue, 120, TimeUnit.SECONDS);
            // System.out.println("存放到redis中的codeKey为: " + redisTemplate.opsForValue().get(codeKey));

            //使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中
            BufferedImage bufferedImage = defaultKaptcha.createImage(codeValue);
            ImageIO.write(bufferedImage, "jpg", jpegOutputStream);

        } catch (IllegalArgumentException e) {
            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
        }

        // 将图片转为64编码
        BASE64Encoder encoder = new BASE64Encoder();
        String base64Img = "data:image/jpeg;base64," + encoder.encode(jpegOutputStream.toByteArray());

        Map<String, String> map = new HashMap<>();
        map.put("codeKey", codeKey);
        map.put("base64Img", base64Img);

        return new JsonResult<>(OK, map);

    }
}

Custom global constants

package com.cy.store.common;

/**
 * @author ZhangHailong
 * @date 2022/5/19 - 10:33
 * @project_name 自定义全局常量
 */
public class Const {

    // 验证码标识前缀
    public final static String CAPTCHA_K = "CAPTCHA";

    // 搜索历史标识前缀
    public final static String HISTORY_K = "HISTORY";
}

Add user login judgment

@RequestMapping(value = "login", method = RequestMethod.POST)
    public JsonResult<User> loginUserController(LoginUserVO loginUser, HttpSession session) {
    
        String realCodeValue = redisTemplate.opsForValue().get(Const.CAPTCHA_K + loginUser.getCodeKey());
        if (realCodeValue == null) {
            throw new KaptchaCodeFailureException("验证码失效");
        }
        if (!loginUser.getSubmitCodeValue().equals(realCodeValue)) {
            throw new VertifyCodeNotMatchException("验证码不正确");
        }
        
        User user = new User();
        user.setUsername(loginUser.getUsername());
        user.setPassword(loginUser.getPassword());
        User resuData = iUserService.loginUser(user);

        // 将登陆成功的用户的uid,username存到session中
        session.setAttribute("uid", resuData.getUid());
        session.setAttribute("username", resuData.getUsername());

        return new JsonResult<>(OK, resuData);
    }

After adding the verification code module, the information that users need to submit for login includes: user name, password, the verification code entered by themselves, and the key corresponding to the verification code image, so the entity class User cannot be used to pick it up, but a value object is used. Define a value object LoginUserVO

package com.cy.store.vo;

import java.util.Objects;

/**
 * @author ZhangHailong
 * @date 2022/5/18 - 13:46
 * @project_name
 */
public class LoginUserVO {

    private String username;
    private String password;
    private String codeKey;
    private String submitCodeValue;

	// 省略get,set

Test verification code interface

Access data.base64Img and get the picture

 

View the validity time of the verification code in the redis visualization tool

 

 

Guess you like

Origin blog.csdn.net/dj1232090/article/details/127335840