基于验证码的轮子还是挺多的,而且都与springboot项目集成的比较好,最简单的方案就是使用开源组件HuTool工具包,HuTool工具包的图片验证码生成支持随机字符串以及算术类型的验证码。
伪代码如下:
xxxxxxxxxx
151
2public class CaptchaVO {
3 /**
4 * 验证码标识符
5 */
6 private String captchaKey;
7 /**
8 * 验证码过期时间
9 */
10 private Long expire;
11 /**
12 * base64字符串
13 */
14 private String base64Img;
15}
验证码控制器:
xxxxxxxxxx
311
2"/captcha") (
3public class CaptchaController {
4 private final String CAPTCHA_KEY = "captcha:verification:";
5
6
7 private RedisUtils redisUtils;
8
9
10 "/get") (
11 public CaptchaVO getCaptcha() throws IOException {
12 // 生成验证码
13 LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
14 lineCaptcha.setGenerator(new RandomGenerator(6));
15 String captchaCode = lineCaptcha.getCode();
16
17 //生成一个随机标识符
18 String captchaKey = UUID.randomUUID().toString();
19 //缓存验证码并设置过期时间
20 redisUtils.set(CAPTCHA_KEY.concat(captchaKey),captchaCode,5000L);
21
22 // 对图片验证码生成Base64编码
23 String str = "data:image/jpeg;base64,";
24 String base64Img = str + lineCaptcha.getImageBase64();
25 CaptchaVO captchaVO =captchaService.cacheCaptcha(content);
26 captchaVO.setCaptchaKey(captchaKey);
27 captchaVO.setExpire(5000L);
28 captchaVO.setBase64Img(base64Img);
29 return captchaVO;
30 }
31}
以上只是随机生成带有干扰线的图片验证码,还可以生成一个GIF格式验证码、圆圈干扰验证码、扭曲干扰验证码的验证码图片,如果需要一个GIF格式的验证码图片,则可以使用cn.hutool.captcha.GifCaptcha
来生成验证码图片,生成方式跟cn.hutool.captcha.LineCaptcha
是一样的。
前端
1、当前端请求到验证码后,将验证码服务返回的CaptchaVO#base64Img
字段转换成验证码图片并展示到前端页面并记录唯一标识CaptchaVO#captchaKey
。
2、发起需要验证码业务接口调用时,将用户输入的验证码和唯一标识当作Header
传递到后端
后端
后端验证验证码的正确性可以单独部署一套服务,提供一个专门验证验证码的接口,每次调用验证码校验接口通过验证后再调业务接口,但是这样会存在业务接口会被暴力破解的风险。所以验证码校验还是需要跟业务紧耦合的方式来做,具体步骤如下:
1、添加一个校验验证码的Filter
继承OncePerRequestFilter
,实现doFilterInternal
方法,并在该方法中来做验证码的校验。
2、在服务配置中添加需要做验证码校验的接口Path,使第一步添加的FIlter生效。
伪代码:
xxxxxxxxxx
141public class ValidateCodeFilter extends OncePerRequestFilter{
2 private final String CAPTCHA_KEY = "captcha:verification:";
3
4
5 private RedisUtils redisUtils;
6
7
8 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
9 //1、获取验证码相关的请求头参数
10 //2、根据流程图中的流程校验验证码
11 //3、如果校验失败则结束并返回请求,如果校验成功则放行请求
12 chain.doFilter(request, response);
13 }
14}
可以将该过滤器单独出来做成一个外部依赖,需要用到该验证码方案的服务都来依赖这个jar包,只需要在外部配置文件中配置需要加验证码的的接口Path即可。
验证码服务跟随业务服务部署,所以部署架构如下: