验证码案例
1. Kaptcha 插件介绍
Kaptcha 是Google的⼀个⾼度可配置的实⽤验证码⽣成⼯具。
1.1 原理
验证码可以客户端生成,也可以服务端生成。对于普通的字符验证码,后端通常分为两部分。
⼀是⽣成验证码内容,根据验证码内容和⼲扰项等,⽣成图⽚,返回给客户端。
⼆是把验证码内容存储起来,校验时取出来进⾏对⽐。
kaptcha插件选择把验证码存储在Session⾥。
1.2 引入依赖
<dependency>
<groupId>com.oopsguy.kaptcha</groupId>
<artifactId>kaptcha-spring-boot-starter</artifactId>
<version>1.0.0-beta-2</version>
</dependency>
1.3 通过配置文件生成验证码生成器
kaptcha:
text-producer:
character:
length: 4
font:
color: blue
items:
# admin captcha
admin:
path: /admin/captcha
session:
key: KAPTCHA_SESSION_KEY
date: KAPTCHA_SESSION_DATE
配置说明:
配置后,可以直接访问http://XXX:port/admin/captcha即可生成验证码。
1.4 需求
- 页面生成验证码
- 输入验证码,点击提交,验证用户输入验证码是否正确,正确则进行页面跳转
1.4.1 约定前后交互接口
需求分析:
后端需要提供两个服务:
- 生成验证码,并返回验证码
- 校验验证码是否正确
接口定义:
- 生成验证码
请求:GET /admin/captcha
响应:图片内容
浏览器给服务器发送⼀个 GET /admin/captcha 这样的请求, 服务器返回⼀个图⽚, 浏览器显⽰在⻚⾯上。
- 校验验证码是否正确
请求:POST /admin/check?inputCaptcha=fgn3
响应:true
根据⽤⼾输⼊的验证码, 校验验证码是否正确. true: 验证成功. false: 验证失败
1.5 服务器端代码:
⽐对Session中存储的验证码是否和⽤⼾输⼊的⼀致,如果⼀致,并且时间在⼀分钟以为就认为成功
@RestController
@RequestMapping("/admin")
public class KaptchaController {
private static final String KAPTCHA_SESSION_KEY = "KAPTCHA_SESSION_KEY";
private static final String KAPTCHA_SESSION_DATE = "KAPTCHA_SESSION_DATE";
private static final long CAPTCHA_TIME_OUT = 1000*60;//过期时间:一分钟,毫秒数
/**
* 校验验证码是否正确
* @param inputCaptcha 用户输入的验证码
* @return
*/
@RequestMapping("/check")
public boolean check(String inputCaptcha, HttpSession session){
// 1.判断输入的验证码是否为空
// 2.获取生成的验证码
// 3.对比用户输入的验证码和生成的验证码是否一致
// 4.确认验证码是否过期
if(!StringUtils.hasLength(inputCaptcha)) {
//验证码为空
return false;
}
// 生成的验证码
String saveCaptcha = (String) session.getAttribute(KAPTCHA_SESSION_KEY);
// 验证码的生成时间
Date saveCaptchaDate = (Date) session.getAttribute(KAPTCHA_SESSION_DATE);
if(inputCaptcha.equalsIgnoreCase(saveCaptcha)) {
// 确认验证码是否过期
if(saveCaptchaDate != null &&
System.currentTimeMillis()-saveCaptchaDate.getTime() < CAPTCHA_TIME_OUT) {
return true;
}
}
return false;
}
}
1.5 前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>验证码</title>
<style>
#inputCaptcha {
height: 30px;
vertical-align: middle;
}
#verificationCodeImg{
vertical-align: middle;
}
#checkCaptcha{
height: 40px;
width: 100px;
}
</style>
</head>
<body>
<h1>输入验证码</h1>
<div id="confirm">
<input type="text" name="inputCaptcha" id="inputCaptcha">
<img id="verificationCodeImg" src="/admin/captcha" style="cursor: pointer;" title="看不清?换一张" />
<input type="button" value="提交" id="checkCaptcha">
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
$("#verificationCodeImg").click(function(){
$(this).hide().attr('src', '/admin/captcha?dt=' + new Date().getTime()).fadeIn();
});
$("#checkCaptcha").click(function () {
$.ajax({
type: "get",
url: "/admin/check",
data: {
inputCaptcha: $("#inputCaptcha").val()
},
success: function(result) {
if(result) {
location.href = "success.html"
} else {
alert("验证码失败!");
}
}
});
});
</script>
</body>
</html>
成功后的跳转页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>验证成功页</title>
</head>
<body>
<h1>验证成功</h1>
</body>
</html>
1.6 运行测试
通过url:http://127.0.0.1:8080/index.html访问服务
输入验证码,跳转页面