java生成前端验证码+验证「kaptcha」

故事扮演 提交于 2019-12-04 20:18:40

1、前言

kaptcha是一个非常实用的短信验证码生成工具,通过简单配置即可实现多样化的验证码。

2、引入依赖

<!--第三方验证码--><dependency>    <groupId>com.github.penggle</groupId>    <artifactId>kaptcha</artifactId>    <version>2.3.2</version></dependency>

3、前台

假设前台调用样式如下:

<img alt="验证码" width="128" height="42"  @click="changeImage" src="项目地址/validate/captcha-image" ref="checkCode"/>

通过调用 /validate/captcha-image 接口地址获取验证码。

4、后台

4.1 controller

@RequestMapping("/captcha-image")public void defaultKaptcha(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) throws Exception{    validateService.defaultKaptcha(httpServletRequest,httpServletResponse);}

4.2 serviceImpl

@Autowiredprivate StringRedisTemplate redisTemplate;@AutowiredDefaultKaptcha defaultKaptcha;//验证码失效时间 15分钟private static final int VALID_CODE_CACHE_EXPIRE_TIME = 900; /** * 生成图片验证码 * @param httpServletRequest request * @param httpServletResponse response */public void defaultKaptcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)throws Exception{    byte[] captchaChallengeAsJpeg = null;    ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();    try {        /*生产验证码字符串并保存到session中*/        String createText = defaultKaptcha.createText();        String key = String.format("login_valid_code_%s", httpServletRequest.getSession().getId());        redisTemplate.opsForValue().set(key, createText, VALID_CODE_CACHE_EXPIRE_TIME, TimeUnit.SECONDS);        //httpServletRequest.getSession().setAttribute("vrifyCode", createText);        //使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中        BufferedImage challenge = defaultKaptcha.createImage(createText);        ImageIO.write(challenge, "jpg", jpegOutputStream);    } catch (IllegalArgumentException e) {        httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);        return;    }    //定义response输出类型为image/jpeg类型,使用response输出流输出图片的byte数组    captchaChallengeAsJpeg = jpegOutputStream.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(captchaChallengeAsJpeg);    responseOutputStream.flush();    responseOutputStream.close();}

补充:DefaultKaptcha是引入kaptcha依赖后即直接可引入的;

如上思路代码已经很清晰了,通过DefaultKaptcha创建验证码文本,然后存入redis一份,用于后面的验证使用;

注意:redis 拼接的 key 规则为 login_valid_code_ + sessionId(session id)

5、效果

前端实际应用效果:

浏览器直接调用接口效果:

6、验证

6.1 controller

从redis中取

/** * 验证验证码 * @return Object */@UnAuthorization@RequestMapping(value = "code/check", method = {RequestMethod.POST})public Object checkCode(@RequestBody @Valid CheckValidateRequest checkValidateRequest , BindingResult bindingResult, HttpServletRequest request) {    return validateService.checkValidateCode(httpServletRequest.getSession().getId(),checkValidateRequest.getValidCode());}

6.2 serviceImpl

/** * 验证短信验证码有效性 * @param mobile 手机号码 或者 sessionId * @param validCode 验证码 * @return boolean */public boolean checkValidateCode(String sessionId, String validCode) {    Object iValidCodeFromRedis = cacheService.getCache(String.format("login_valid_code_%s", sessionId));    String sValidCodeFromRedis = String.valueOf(iValidCodeFromRedis);    if (StringUtils.isNotBlank(sValidCodeFromRedis) && validCode.equalsIgnoreCase(sValidCodeFromRedis)) {        return true;    }    throw new CommonException(ValidateStatusEn.CHECK_VALID_CODE_FAILED.getErrorMsg(), ValidateStatusEn.CHECK_VALID_CODE_FAILED.getErrorCode());}

补充:通过 login_valid_code_ + sessionIdredis 中获取验证码进行校验。


我创建了一个用来记录自己学习之路的公众号,感兴趣的小伙伴可以关注一下微信公众号:niceyoo

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!