java生成前端驗證碼+驗證「kaptcha」


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

@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依賴后即直接可引入的;

如上思路代碼已經很清晰了,通過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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM