基于验证码的轮子还是挺多的,而且都与springboot项目集成的比较好,最简单的方案就是使用开源组件HuTool工具包,HuTool工具包的图片验证码生成支持随机字符串以及算术类型的验证码。
伪代码如下:
xxxxxxxxxx1512public 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}验证码控制器:
xxxxxxxxxx3112("/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生效。
伪代码:
xxxxxxxxxx141public 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即可。
验证码服务跟随业务服务部署,所以部署架构如下: