女朋友问我怎么实现后端校验验证码

风和日丽的早上开车和女朋友一起上班,说道一些有的没的技术,突然女朋友问我怎么实现后端校验验证码,我之前是看过一点别人写的逻辑,支支吾吾的结果没讲清楚,女朋友说我装逼失败,这怎么能忍,于是奋发图强学校了一下我们公司大佬的逻辑,原来核心就是开源的kaptcha

先来一段官方介绍,用来表示这是一篇技术博客:

Kaptcha 简介

Kaptcha 是一个非常实用的验证码生成工具,它是基于SimpleCaptcha的开源项目。通过调整Kaptcha配置可以生成各种样式的验证码。

使用Kaptcha可以方便的配置以下细节:

  • 验证码的字体
  • 验证码字体的大小
  • 验证码字体的字体颜色
  • 验证码内容的范围
  • 验证码图片的大小,边框,边框粗细,边框颜色
  • 验证码的干扰线
  • 验证码的样式
好了,正式完了就开始说一下实现思路吧,其实也挺简单
  1. 前端请求后台接口,后台随机生成一个uuid给前端

1557362747956

  1. 前端拿到uuid之后,通过这个uuid请求后台,后台通过uuid生成一张验证码图片返给前端

    1557362821183

1557362862840

[^这里说一下后端的实现:其实这个uuid是为了和图片做绑定而产生的,在数据库的表示如下图所示]:

1557362963541

  1. 登录校验验证码:用户登录填写账号、密码、验证码,带着uuid (重点:带着uuid,这个uuid其实就相当于这张图片验证码的一个识别,只有带着这个,后台才知道你用的是哪张验证码,才有办法去校验)调用后台登录接口,后台 通过带过来的uuid去查询这张图片验证码的文本验证码是多少,然后比对校验就可以了,是不是很简单。

当然验证码都是有失效时间的,还有验证码用完就删掉啊,这个就不多说了,聪明的人自然会懂,我女朋友那么聪明,应该会懂的 O(∩_∩)O~

下面的是具体实现代码,留作备用观摩。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@GetMapping("captcha.jpg")
public void captcha(HttpServletResponse response, @RequestParam String uuid) {

//1.进入函数
logger.info("-> auth login: generate captcha");

//2 验证uuid格式
if(!TypeValidatorUtil.isUuid(uuid)){
logger.info("-- auth login: uuid not valid");
throw new CPException("uuid 不合法");
}

//3.response设置
response.setHeader("Cache-Control", "no-store, no-cache");
response.setContentType("image/jpeg");

try{
//4.生成图片验证码并将对应uuid和code保存数据库
BufferedImage image = authCaptchaService.getCaptcha(uuid);

//5.图片验证码返回到前端
ServletOutputStream out = response.getOutputStream();
ImageIO.write(image, "jpg", out);

//6.正常退出函数
logger.info("<- auth login: generate captcha");

//7.关闭连接
IOUtils.closeQuietly(out);
}catch (IOException e){
logger.error(e.getMessage());
throw new CPException("IO错误");
}catch (Exception e){
logger.error(e.getMessage());
throw new CPException("获取验证码失败");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
public BufferedImage getCaptcha(String uuid) {
if(StringUtils.isBlank(uuid)){
throw new CPException("uuid不能为空");
}
//生成文字验证码
String code = producer.createText();

AuthCaptchaEntity captchaEntity = new AuthCaptchaEntity();
captchaEntity.setUuid(uuid);
captchaEntity.setCode(code);
//5分钟后过期
captchaEntity.setExpireTime(DateUtil.addDateMinutes(new Date(), 5));
authCaptchaDao.insertCaptcha(captchaEntity);

return producer.createImage(code);
}
1
2
3
4
5
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 生成验证码配置
*
* @author zfan
*/
@Configuration
public class KaptchaConfig {

@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");
Config config = new Config(properties);
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}

附:

JCaptcha简介

JCapthca是一个开源的用来生成图形验证码的Java开源组件,它非常强大,不光是可以生成图片式的验证码,还可以生成声音式的。

JCaptcha是CAPTCHA里面的一个比较著名的项目。

0%