15.登录模块增加验证码部分

验证码登录流程,别人博客看的

在这里插入图片描述

实现过程

  • 之前SSM其实就做过了,保存session中,只不过之前是将验证码的值放到session中,而这次是将验证码的值保存到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中r配置redis

    spring.redis.port=6379
    spring.redis.host=127.0.0.1
    spring.redis.database=0
    
  • kaptcha配置信息

    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中存放的验证码的key的格式是:CAPTCHA+随机数,其value就是验证码的实际值

    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);
    }
  • 在增加验证码的模块后,用户登录需要提交的信息有:用户名、密码、自己输入的验证码、验证码图片对应的key,所以就不能用实体类User去接,而是使用值对象,定义一个值对象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可视化工具中查看验证码的有效时间
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值