1. 引言
Redis是一种基于key-value的非关系型数据库,它具有高性能、高可用性和可扩展性等优点。结合SpringBoot框架使用Redis,可以很好地提高访问速度以及保证系统的可靠性。验证码作为常用的用户验证方式,需要频繁地进行验证,配合Redis缓存可以大大提升验证效率,降低服务器压力。在本文中,我们将介绍如何在SpringBoot中整合Redis缓存验证码。
2. 环境准备
2.1. 技术栈
本文使用的开发工具及技术栈如下:
IDEA 2020.3
SpringBoot 2.4.2
Redis 6.0.10
Thymeleaf 3.0.11.RELEASE
2.2. 依赖引入
首先,在SpringBoot的Maven项目中,需要添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2.3. Redis服务配置
在使用Redis之前,首先需要启动Redis服务,并在配置文件application.properties中添加如下Redis参数:
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.database=0
spring.redis.password=
spring.redis.timeout=30000
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-wait=-1
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.min-idle=0
3. 实现验证码缓存
3.1. 编写验证码生成工具类
我们先来编写一个生成验证码的工具类:
public class VerifyCodeUtil {
// 允许输入的字符
private static final String VERIFY_CODES = "0123456789ABCDEFHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
public static String generateVerifyCode(int verifySize) {
String sources = VERIFY_CODES;
int codesLen = sources.length();
Random rand = new Random(System.currentTimeMillis());
StringBuilder verifyCode = new StringBuilder(verifySize);
for (int i = 0; i < verifySize; i++) {
verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1))));
}
return verifyCode.toString();
}
}
该工具类可以生成指定长度的验证码。
3.2. 编写验证码控制器
接下来,我们来编写一个简单的验证码控制器:
@RestController
public class VerifyCodeController {
@Autowired
private StringRedisTemplate redisTemplate;
@GetMapping(value = "/verifyCode/{uuid}")
public void getVerifyCode(@PathVariable("uuid") String uuid, HttpServletResponse response) throws Exception {
// 设置响应头信息
response.setContentType("image/png");
// 生成随机验证码
String verifyCode = VerifyCodeUtil.generateVerifyCode(4);
// 获取某些配置
ByteArrayInputStream bis = VerifyCodeUtil.getImage(verifyCode);
redisTemplate.opsForValue().set(uuid, verifyCode, 300, TimeUnit.SECONDS); // 缓存验证码
ServletOutputStream sos = response.getOutputStream();
ByteStreams.copy(bis, sos);
sos.flush();
}
}
由于我们使用了Redis缓存验证码,所以需要注入字符串型的Redis操作对象,这里使用了spring-data-redis提供的StringRedisTemplate类。@GetMapping注解表示该方法为处理GET请求的方法,其中通过VerifyCodeUtil生成验证码,并缓存到Redis中。在获取验证码时,直接从Redis中取出并返回给前端。
3.3. 验证码验证
在验证码验证的逻辑中,先要从Redis中获取对应的验证码,并对比前端传来的验证码是否一致。
public boolean validateVerifyCode(String uuid, String code) {
String verifyCode = redisTemplate.opsForValue().get(uuid);
redisTemplate.delete(uuid);
if (verifyCode == null || "".equals(verifyCode) || !verifyCode.equalsIgnoreCase(code)) {
return false;
}
return true;
}
在验证完成后,应将Redis中的验证码缓存删除,以防止验证码被多次利用。
4. 借助Thymeleaf进行页面展示
为了更好地展示验证码,我们可以使用Thymeleaf模板引擎来进行页面展示。下面是一个简单的登录页面,其中通过标签来展示验证码图片,并通过JavaScript代码将验证码缓存到Redis中。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录页</title>
</head>
<body>
<form action="#" method="post">
<div>
<label>用户名:</label><input type="text" name="username">
</div>
<div>
<label>密码:</label><input type="password" name="password">
</div>
<div>
<label>验证码:</label><input type="text" name="verifyCode">
<img id="verifyCodeImg" th:src="@{'/verifyCode/'+ ${UUID}}"/>
<a href="javascript:void(0);" onclick="document.getElementById('verifyCodeImg').src='/verifyCode/'+Math.random();">刷新</a>
</div>
<div>
<button type="submit">登录</button>
</div>
</form>
<script>
function flushVerifyCode() {
$.get({
url: "/verifyCode/" + Math.random(),
success: function (data) {
var uuid = data['uuid'];
$('#verifyCodeImg').attr('th:src', "@{'/verifyCode/'+ ${UUID}}".replace('${UUID}', uuid));
}
});
}
$(document).ready(function () {
flushVerifyCode();
});
$(':submit').click(function (e) {
e.preventDefault();
$.ajax({
url: '/login',
type: 'post',
contentType: 'application/x-www-form-urlencoded;charset=utf-8',
dataType: 'json',
data: $('form').serialize(),
success: function (data) {
if (data.code == 0) {
alert('登录成功');
} else {
alert('登录失败:' + data.msg);
flushVerifyCode();
}
},
error: function () {
alert('登录请求异常');
}
});
})
</script>
</body>
</html>
5. 总结
通过上述介绍,我们了解了如何在SpringBoot中整合Redis缓存验证码,并且在Thymeleaf模板引擎中展示验证码。在实际项目中,验证码是常用的用户验证方式,使用验证码缓存可以大大提高验证效率,降低服务器压力。