• 【SpringBoot】实现引入登录时的验证码功能


    一、前言

    今天在实现登录功能时,突然想到大部分网站都会设置的一个验证码功能,引入可以用于拦截机器非法攻击等情况,于是我立即就去查阅相关资料,最后决定使用easy-captcha工具包提供的验证码来实现验证码验证功能。

    easy-captcha是一款国人开发的验证码工具,支持GIF、中文、算术等类型,可用于Java Web等项目,生成的验证码形式如下图所示。
    在这里插入图片描述

    由于我没有太高的要求,就挑了最简单的字母+数字的普通类型验证码来实现。在一番捣鼓后,解决了一些小问题,算是很简单地就实现了,下面我就简单讲一下实现步骤。

    二、实现

    (一)添加easy-captcha依赖

    添加该依赖的方式有多种,推荐去maven依赖库官网搜索easy-captcha,以添加maven依赖的形式添加。据2022/8/5,也就是我写到这里的目前为止,我只看见了一个版本,大家也可以直接复制下面的代码去pom.xml文件里,黏贴后同时点击ctrl+shift+o进行添加。

            
            <dependency>
                <groupId>com.github.whvcsegroupId>
                <artifactId>easy-captchaartifactId>
                <version>1.6.2version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (二)后端控制层生成验证码图并储存验证码,前端视图层进行请求获取

    后端控制层代码如下:

    package com.example.malldemo.controller.common;
    
    import com.wf.captcha.SpecCaptcha;
    import com.wf.captcha.base.Captcha;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @Controller
    @RequestMapping("/common")
    public class commonCotroller {
    
        @GetMapping("/kaptcha")
        public void defaultKaptcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
            httpServletResponse.setHeader("Cache-Control", "no-store");
            httpServletResponse.setHeader("Pragma", "no-cache");
            httpServletResponse.setDateHeader("Expires", 0);
            httpServletResponse.setContentType("image/gif");
    
            // 三个参数分别为宽、高、位数
            SpecCaptcha captcha = new SpecCaptcha(150, 30, 4);
    
            // 设置字体
            captcha.setCharType(Captcha.FONT_9);
    
            // 验证码存入session
            httpServletRequest.getSession().setAttribute("verifyCode", captcha.text().toLowerCase());
    
            // 输出图片流
            captcha.out(httpServletResponse.getOutputStream());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    前端thymeleaf视图层代码如下:

    <div class="row">
      <div class="col-6">
          <input type="text" class="form-control" name="verifyCode" placeholder="请输入验证码" required="true">
      div>
      <div class="col-6">
          <img alt="点击图片刷新!" src="/common/kaptcha" onclick="this.src='/common/kaptcha?d='+new Date()*1">
      div>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里访问后端验证码路径/common/kaptcha,由于验证码是图片形式,所以将其显示在img标签中。然后定义onclick方法,在点击该img标签时可以动态切换显示一个新的验证码。点击时访问的路径为’/common/kaptcha?d='+new Date()*1,即原来的验证码路径后面带上一个时间戳参数 d。时间戳是会变化的,所以每次点击都会是一个与之前不同的请求。

    (三)表单提交后,登录时的验证实现

    //如果表单提交填入的验证码为空
    if (StringUtils.isEmpty(verifyCode)) {
    	session.setAttribute("errorMsg", "验证码不能为空");
    	//...下面表单提交填入的验证码为空后的动作
    }
    
    String kaptchaCode = session.getAttribute("verifyCode") + "";
    //如果验证码错误
    if (StringUtils.isEmpty(kaptchaCode) || !(verifyCode.toLowerCase()).equals(kaptchaCode)) {
        session.setAttribute("errorMsg", "验证码错误");
        //...下面写验证码错误后的动作
    }
    
    //...若填入提交的验证码既不为空也不错误,可以写接下来的验证或登录事件了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    三、最后

    本篇文章讲的是传统输入式验证码在SpringBoot过程中的引入实现,经过以上三步基本是可以实现的了。在实现过程中,我也遇到了许多问题,比如图片中某个字母明明是大写的,生成的验证码中那个字母却是小写的,所以也导致了屡验屡错。思考过后,我以toLowerCase()将生成存入session的验证码转变为小写的,并且在登录表单提交后验证时,也以toLowerCase()将填入提交的验证码转为小写,这样就可以以小写匹配小写,规避了原本easy-captcha工具包在大小写问题上出错的可能。

    如果大家有什么问题,也欢迎提出哈,一起讨论一起解决。

  • 相关阅读:
    SQLAlchemy详解
    自费访学|金融公司高管赴世界名校伯克利交流
    Himall商城-公共方法
    Linux系统上使用SQLite
    如何开发新客户?有哪些高效率方法?
    如何把Map的value转为list
    进阶 P7P8 岗敲门金砖:京东 T5 级架构师出品高并发核心编程手册,涨薪 10k 的秘诀
    Android12/13 解决WiFi输入框被遮挡问题
    【panel】屏EMC展频调试方法
    私藏!资深数据专家SQL效率优化技巧 ⛵
  • 原文地址:https://blog.csdn.net/peng_YuJun/article/details/126187232