Spring Boot全后端实现验证码

  1. 验证码通常是利用前端技术实现的,前端的验证码需要先在后端进行保存,再传到前端,再于前端传输的数据对比校验。一些前后端分离项目的工作量大大增加,而如果完全是由后端独立实现的,那么在代码量和复杂程度上就大大降低了。
  2. 框架:Spring Boot+Mybatis-plus,依赖组件: kaptcha
  3. 代码实现:

         3.1.pom.xml依赖

<dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!--使用ApiModel需要导入swagger依赖-->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.5.13</version>
        </dependency>
        <!--生成验证码-->
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>


        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

         3.2.工具类

  package com.example.config;

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

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"); //是否有边框 yes有 no没有
        properties.put("kaptcha.textproducer.font.color", "blue"); //验证码字体颜色
        properties.put("kaptcha.image.width", "150"); //验证码图片的宽
        properties.put("kaptcha.image.height", "40"); //验证码图片的高
        properties.put("kaptcha.textproducer.font.size", "30"); //验证码字体大小
        properties.put("kaptcha.session.key", "verifyCode"); //存储在session中值的key
        properties.put("kaptcha.textproducer.char.length", "5"); //验证码字符个数
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }

}

         3.3.控制层

package com.example.controller;
import com.example.config.Result;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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;

@RestController
//@Controller
@Api(tags = "验证码管理")
@RequestMapping("/code")
public class VerificationCodeController {

    @Autowired
    private DefaultKaptcha captchaProducer;


    @ApiOperation("获取验证码图片")
    @GetMapping("/getVerificationCodePhoto")
//    @RequestMapping("/getVerificationCodePhoto")
    public void getVerificationCodePhoto(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        byte[] captchaOutputStream = null;
        ByteArrayOutputStream imgOutputStream = new ByteArrayOutputStream();
        try {
            //生成验证码
            String verifyCode = captchaProducer.createText();
            //验证码字符串保存到session中
            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();
    }


    @ApiOperation("获取验证码")
    @GetMapping("/getVerificationCode")
    public Result getVerificationCode(HttpServletRequest request) {
        Result result = new Result();
        String verifyCode = captchaProducer.createText();
        request.getSession().setAttribute("verifyCode", verifyCode);
        result.setData(verifyCode);
        return result;
    }

}

方法1:返回转化后的url,到前端直接以图片形式显示

 

方法2:返回字符串

 

测试工具:PostMan

 

         3.4.前端login.html,在static文件下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
验证码:<input type="text" name="code">
<img src="/code/getVerificationCodePhoto" alt="验证码"  align="bottom" style="cursor:pointer;" title="看不清可单击图片刷新" onclick="this.src='/code/getVerificationCodePhoto'" />
</body>
</html>

4.使用说明

  1. Result类:R类的统一处理,返回结果统一。不过在后端传输Byte-图片的情况下,无法使用R类。(第一个方法是转化为byte类型后,返回图片的url地址,到页面上就是图片形式了)。第二个返回字符串的方法中才使用的R类,这里的R类建议自己编写,也可以不用R类,直接返回字符串也可。
  2. 前端点击验证码可以进行刷新,onclick的作用,点击后方法重新被调用。 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>