当前的诸多系统中,都加入了图形验证码的校验,用来限制不法人员对接口的恶意尝试。
使用 Google 验证码工具 Kaptcha ,直接生成一张验证码图片,能满足我们生成验证码的绝大部分需求。
实现步骤
- 首先通过 Kaptcha 提供的生成器生成验证码信息
- 使用 Kaptcha 生成验证码图片
- 将验证码信息保存到当前请求的 Seesion 中
- 校验时,比较 Session 中的验证码和用户传递的验证码是否一致
引入 Kaptcha
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
Kaptcha 配置类
@Configuration
public class KaptchaConfig {
@Bean
public Producer kaptchaProducer() {
Properties properties = new Properties();
//边框样式
properties.setProperty("kaptcha.border", "yes"); //是否边框
properties.setProperty("kaptcha.border.color", "black"); //边框颜色
//图片大小
properties.setProperty("kaptcha.image.width", "100"); //图片长度
properties.setProperty("kaptcha.image.height", "40"); //图片宽度
//验证码内容
properties.setProperty("kaptcha.textproducer.char.string", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); //验证码内容集合
properties.setProperty("kaptcha.textproducer.char.length", "4"); //验证码长度
properties.setProperty("kaptcha.textproducer.char.space", "2"); //验证码间隔
properties.setProperty("kaptcha.textproducer.font.names", "微软雅黑"); //验证码字体
properties.setProperty("kaptcha.textproducer.font.size", "32"); //验证码字体大小
properties.setProperty("kaptcha.textproducer.font.color", "0,0,0"); //验证码字体颜色
//干扰项
properties.setProperty("kaptcha.noise.impl", "com.google.code.kaptcha.impl.NoNoise"); //实现类
properties.setProperty("kaptcha.noise.color", "blue"); //干扰颜色
//渲染效果
//水纹 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");
//背景图片渲染器
properties.setProperty("kaptcha.background.impl", "com.google.code.kaptcha.impl.DefaultBackground");
properties.setProperty("kaptcha.background.clear.from", "251,255,242");
properties.setProperty("kaptcha.background.clear.to", "202,235,216");
//文字渲染器
properties.setProperty("kaptcha.word.impl", "com.google.code.kaptcha.text.impl.DefaultWordRenderer");
//使用默认图片实现类
DefaultKaptcha kaptcha = new DefaultKaptcha();
Config config = new Config(properties);
kaptcha.setConfig(config);
return kaptcha;
}
}
生成验证码接口
@Autowired
Producer kaptchaProducer;
@GetMapping("kaptcha/create")
public R create(HttpServletRequest request) {
String text = kaptchaProducer.createText();
BufferedImage image = kaptchaProducer.createImage(text);
HttpSession session = request.getSession();
session.setAttribute("kaptcha", text);
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpeg", outputStream);
String base64 = Base64.getEncoder().encodeToString(outputStream.toByteArray());
return R.success("data:image/jpeg;base64," + base64.replaceAll("\r\n", ""));
} catch (IOException e) {
//14001 验证码生成失败
return R.failure(14001,"验证码生成失败");
}
}
简单校验接口
/**
* 校验验证码是否正确
* @return
*/
@GetMapping("kaptcha/checkImgCode")
public R checkImgCode(@RequestParam("imgCode")String imgCode, HttpServletRequest request){
if (StringUtils.isBlank(imgCode)) {
//14002 验证码为空提示
return R.failure(14002,"验证码不能空");
}
HttpSession session = request.getSession();
String kaptcha = (String)session.getAttribute("kaptcha");
if (null == kaptcha || Objects.requireNonNull(code).compareToIgnoreCase(kaptcha) != 0) {
//14003 验证码不正确
R result = R.failure(14003,"验证码不正确");
//校验失败后重置图形验证码
result.setResult(create(request));
return result;
}
return R.success();
}
测试
请求生成图形验证码 /kaptcha/create
前端展示图片
校验验证码是否正确
错误验证码 /kaptcha/checkImgCode?imgCode=111
正确验证码 /kaptcha/checkImgCode?imgCode=KIKH