ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-06-02 18:03:48  阅读:213  来源: 互联网

标签:httpServletRequest code java String kaptcha 验证码 httpServletResponse defaultKaptc


1、前言

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

2、引入依赖

<dependency>
    <groupId>com.github.pengglegroupId>
    <artifactId>kaptchaartifactId>
    <version>2.3.2version>
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_ + sessionId 从 redis 中获取验证码进行校验。

标签:httpServletRequest,code,java,String,kaptcha,验证码,httpServletResponse,defaultKaptc
来源: https://blog.51cto.com/u_11827525/2847662

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有