kaptcha是一個很是實用的短信驗證碼生成工具,經過簡單配置便可實現多樣化的驗證碼。前端
<dependency> <groupId>com.github.pengglegroupId> <artifactId>kaptchaartifactId> <version>2.3.2version> dependency>
假設前臺調用樣式以下:git
<img alt="驗證碼" width="128" height="42" @click="changeImage" src="項目地址/validate/captcha-image" ref="checkCode"/>
經過調用 /validate/captcha-image 接口地址獲取驗證碼。github
@RequestMapping("/captcha-image") public void defaultKaptcha(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) throws Exception{ validateService.defaultKaptcha(httpServletRequest,httpServletResponse); }
@Autowired private StringRedisTemplate redisTemplate; @Autowired DefaultKaptcha 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依賴後即直接可引入的;redis
如上思路代碼已經很清晰了,經過DefaultKaptcha建立驗證碼文本,而後存入redis一份,用於後面的驗證使用;數組
注意:redis 拼接的 key 規則爲 login_valid_code_ + sessionId(session id)瀏覽器
前端實際應用效果:session
瀏覽器直接調用接口效果:app
從redis中取ide
/** * 驗證驗證碼 * @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()); }
/** * 驗證短信驗證碼有效性 * @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_ + sessionId 從 redis 中獲取驗證碼進行校驗。工具