选择背景:早期所里项目用的是读取式的验证码获取方式,整体大概流程就是预先加载验证码的文本(含有大量的随机字母和数字组成的一个个验证码文本),随着这次项目做微服务的架构升级和开放API的选择,最终将验证码的获取方式替换成了生成式,采用的是Google的kaptcha包提供的API(PS:如果不是系统架构的变动,这边要求一次性升级,真不想动屎山)
下面是具体的实现:
a.引入jar包
<!-- 版本大家可以按照自己项目要求来,这里做演示就随便引入的版本 -->
<!-- PS:版本选择是一个很麻烦的过程,之前接触不到所以都没关注过 -->
<kaptcha.version>0.0.9</kaptcha.version>
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
b.配置验证码的相关参数(没有配在xml文件里,直接写的配置config)
/**
* 生成验证码配置
*/
@Configuration
public class KaptchaConfig {
//DefaultKaptcha是Producer的实现类
@Bean
public DefaultKaptcha producer() {
Properties properties = new Properties();
properties.put("kaptcha.border", "no");
properties.put("kaptcha.textproducer.font.color", "black");
properties.put("kaptcha.textproducer.char.space", "5");
properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋体,楷体,微软雅黑");
Config config = new Config(properties);
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
c.生成验证码文本和图片-CaptchaService
//DefaultKaptcha 配置就是为了注入到Producer里的 不懂的可以去看下开发文档
@Autowired
private Producer producer;
@Override
public BufferedImage getCaptcha(String uuid) {
//这里UUID是为了验证唯一性
if(StringUtils.isBlank(uuid)){
throw new RRException("uuid不能为空");
}
//生成文字验证码
String code = producer.createText();
//SysCaptchaEntity验证码实体类 *入库
SysCaptchaEntity captchaEntity = new SysCaptchaEntity();
captchaEntity.setUuid(uuid);
captchaEntity.setCode(code);
//5分钟后过期
captchaEntity.setExpireTime(DateUtils.addDateMinutes(new Date(), 5));
this.save(captchaEntity);
//生成图片
return producer.createImage(code);
}
d.返回给controller,推置前端,结束。
@Autowired
private CaptchaService captchaService;
/**
* 验证码
*/
@GetMapping("captcha.jpg")
public void captcha(HttpServletResponse response, String uuid)throws IOException {
response.setHeader("Cache-Control", "no-store, no-cache");
response.setContentType("image/jpeg");
//获取图片验证码
BufferedImage image = captchaService.getCaptcha(uuid);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(image, "jpg", out);
IOUtils.closeQuietly(out);
}
3.上面就是使用Google的kaptcha生成验证码的过程,至于验证码的验证过程还是老的那一套,通过uuid去库中取,为空就返回特定错误给前端进行友好提示;有的话就先删除库里的验证码那条数据,然后将用户输入的验证码和库里获取到的比对,同时验证是否过期即可。这里没有做什么改动,就不贴代码了。