Java后端利用DefaultKaptcha生成验证码及校验(缓存在Redis中)
在Java后端进行验证码的生成,可实现验证码开关、缓存在Redis中。一、设计思路在pom文件中引入DefaultKaptcha的依赖(Jar包)。在CaptchaConfig类中配置验证码相关的参数。利用DefaultKaptcha实现类生成验证码图片。利用Redis数据库对验证码进行缓存。利用ImageIO类将验证码图片以流形式写入到内存中。前端页面利用Img标签的src属性,根据Base64
·
一、设计流程
- 在pom文件中引入DefaultKaptcha的依赖(Jar包)。
- 在CaptchaConfig类中配置验证码相关的参数。
- 利用DefaultKaptcha实现类生成验证码图片。
- 利用Redis数据库对验证码进行缓存。
- 利用ImageIO类将验证码图片以流形式写入到内存中。
- 前端页面利用Img标签的src属性,根据Base64编码格式数据获取验证码图片显示。
- 校验时,从Redis中取出验证码并删除,进行判断是否正确。
二、实现过程
1、在pom文件中引入DefaultKaptcha的依赖。
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
2、在CaptchaConfig类中配置验证码相关的参数(字符验证码)。
/**
* 验证码配置参数
*
* @author LBF
*/
@Configuration
public 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
*/
@RestController
public 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;
});
},
<!-- 利用img标签,src属性根据Base64编码格式数据来获取验证码图。 -->
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div>
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数据库作为缓存,最终取出并进行验证。在设计过程中,仍然存在许多未能充分理解的位置,若在使用过程中出现问题或有更好的实现思路,可分享/指出,共同学习进步。
更多推荐
已为社区贡献4条内容
所有评论(0)