> 文档中心 > Java后端利用DefaultKaptcha生成验证码及校验(缓存在Redis中)

Java后端利用DefaultKaptcha生成验证码及校验(缓存在Redis中)


一、设计流程

  1. 在pom文件中引入DefaultKaptcha的依赖(Jar包)。
  2. 在CaptchaConfig类中配置验证码相关的参数。
  3. 利用DefaultKaptcha实现类生成验证码图片
  4. 利用Redis数据库对验证码进行缓存
  5. 利用ImageIO类将验证码图片以流形式写入到内存中。
  6. 前端页面利用Img标签的src属性,根据Base64编码格式数据获取验证码图片显示。
  7. 校验时,从Redis中取出验证码并删除,进行判断是否正确。

二、实现过程

1、在pom文件中引入DefaultKaptcha的依赖。

       com.github.penggle  kaptcha  2.3.2     

 2、在CaptchaConfig类中配置验证码相关的参数(字符验证码)。

/ * 验证码配置参数 * * @author LBF */@Configurationpublic class CaptchaConfig{    /     * 配置生成字符验证码的参数     * @return     */    @Bean(name = "captchaBean")    public DefaultKaptcha getKaptchaBean()    { DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); // 初始化一个Propertis对象,设定验证码参数 Properties properties = new Properties(); // 设置验证码图片宽度,默认为200 properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160"); // 设置验证码图片高度,默认为50 properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60"); // 验证码文本字符大小 默认为40 properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38"); // 设置边框,默认有  yes/no properties.setProperty(KAPTCHA_BORDER, "yes"); // 设置验证码文本字符颜色,默认为Color.BLACK properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black"); // KAPTCHA_SESSION_KEY properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode"); // 验证码文本字符长度,默认为5 properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); // 验证码文本字体样式,默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize) properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier"); // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy"); // 配置其参数 Config config = new Config(properties); // 使验证码参数生效 defaultKaptcha.setConfig(config); return defaultKaptcha;    }}

 3、验证码操作处理类。

1、利用DefaultKaptcha实现类生成验证码图片。

2、利用Redis数据库对验证码进行缓存。

3、利用ImageIO类将验证码图片以流形式写入到内存中。

/ * 验证码操作处理类  (可生成数字/字母) * * @author LBF */@RestControllerpublic class CaptchaController{    // Producer接口(DefaultKaptcha为接口的实现类)    @Resource(name = "captchaBean")    private Producer captchaProducer;    // Redis缓存对象    @Autowired    private RedisCache redisCache;    /     * 生成验证码方法     */    @GetMapping("/test")    public AjaxResult getCode() throws IOException    { // 自己封装的一个数据结果返回体,默认成功, AjaxResult ajax = AjaxResult.success(); // 生成UUID,拼接用以作验证码的唯一标识 String uuid = IdUtils.simpleUUID(); // 设置缓存在Redis中验证码的KEY值 String verifyKey = "captcha_codes:" + uuid; // 保存生成的验证码 String capStr = null; // 保存验证码正确结果(设置缓存在Redis中验证码的Value值) String code = null; BufferedImage image = null; // 生成字符串验证码 // 生成验证码与正确结果一致 capStr = code = captchaProducer.createText(); // 生成图片 image = captchaProducer.createImage(capStr); // 向Redis中缓存基本对象,为了以后进行校验验证码(验证码KEY、正确结果code、验证码过期时间、时间颗粒度(以某计量为单位)) redisCache.setCacheObject(verifyKey, code, 2, TimeUnit.MINUTES); // 图片信息转换成二进制流信息输出 FastByteArrayOutputStream os = new FastByteArrayOutputStream(); try {     // 通过ImageIO将图片以jpg格式,以流形式写入内存中     ImageIO.write(image, "jpg", os); } catch (IOException e) {     // 异常返回      return AjaxResult.error(e.getMessage()); } ajax.put("uuid", uuid); // 利用Base64工具类,转换成字符数组输出给前端 ajax.put("img", Base64.encode(os.toByteArray())); return ajax;    }}

 4、前端页面利用Img标签的src属性,根据Base64编码格式数据获取验证码图片显示。

    // 获取验证码方法    getCode() {      getCodeImg().then(res => {   this.codeUrl = "data:image/gif;base64," + res.img;   this.loginForm.uuid = res.uuid;      });    },
        

 5、校验输入验证码。

    /     * 校验验证码     *      * @param code 此处code为用户输入的验证码     * @param uuid 唯一标识     * @return 结果     */    public void validateCaptcha(String code, String uuid)    { // 验证码的KEY值 String verifyKey = "captcha_codes:" + uuid; // 从Redis中,根据KEY值获取Value值(正确验证码),即获取生成验证码时向Redis中缓存的数据 String captcha = redisCache.getCacheObject(verifyKey); // 删除Redis中的KEY值 redisCache.deleteObject(verifyKey); if (captcha == null) {     // 若Redis中没有KEY对应的Value值,则可说明验证码过期被删除     throw new CaptchaExpireException(); } if (!code.equalsIgnoreCase(captcha)) {     // 调用equalsIgnoreCase方法,进行字符判断是否相等     throw new CaptchaException(); }    }

三、测试结果(测试字符验证码校验结果)

以消息提示窗口作为测试观察------------->>>验证码正确情况

 

 以消息提示窗口作为测试观察------------->>>验证码错误情况

 

四、总结 

     本文介绍采用DefaultKaptcha类生成验证码,使用Redis数据库作为缓存,最终取出并进行验证。在设计过程中,仍然存在许多未能充分理解的位置,若在使用过程中出现问题或有更好的实现思路,可分享/指出,共同学习进步。

神片云