15. 로그인 모듈에 인증코드 부분 추가

타인의 블로그에서 읽은 인증번호 로그인 과정

구현 프로세스

  • 실제로 SSM은 이전에 세션에 저장하는 방식으로 작업을 수행했지만 인증 코드 값을 세션 에 넣기 전에는 확인 코드 값을 Redis에 저장하고 만료 시간을 120으로 설정했습니다. 초.

  • Redis 및 Kaptcha 종속성 소개

  • <!--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>
    

 application.properties에서 Redis 구성

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

캅차 구성 정보

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;
    }

}

사용자가 로그인 페이지 login.html에 접속하면 페이지가 로드된 후 인증 코드 이미지를 얻기 위한 요청이 전송됩니다. 처리 과정은 다음과 같습니다: ① 반환된 이미지 형식은 base64 인코딩입니다. ② 저장된 인증 코드 키 형식입니다. Redis의 내용은 CAPTCHA+임의의 숫자이며 해당 값은 인증 코드의 실제 값입니다.

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);

    }
}

사용자 정의 전역 상수

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";
}

사용자 로그인 판단 추가

@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);
    }

인증 코드 모듈을 추가한 후 사용자가 로그인을 위해 제출해야 하는 정보에는 사용자 이름, 비밀번호, 직접 입력한 인증 코드, 인증 코드 이미지에 해당하는 키가 포함되므로 사용자 엔터티 클래스를 선택하는 데 사용할 수 없습니다. 하지만 값 개체가 사용됩니다. 값 개체 정의 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

테스트 인증 코드 인터페이스

data.base64Img에 액세스하여 사진을 얻으세요.

 

Redis 시각화 도구에서 인증 코드의 유효 시간을 확인하세요.

 

 

추천

출처blog.csdn.net/dj1232090/article/details/127335840