一、 环境准备
1. 解决思路
- 后端使用 easy-captcha 创建验证码对象。
- 将验证码文本存储到 redis 中,并生成一个随机的 key。
- 将验证码的 base64 字符串和 key 返回给前端。
- 前端通过 base64 字符串显示验证码图片,并将 key 保存起来。
- 登录时,前端将用户输入的验证码和 key 发送到后端。
- 后端通过 key 从 redis 中获取验证码文本,并进行比对验证。
2. 接口文档
url
get /captcha
参数
无
返回
{
"msg": "操作成功",
"code": 200,
"data": {
"uuid": "b71fafb1a91b4961afb27372bd3af77c",
"captcha": "data:image/png;base64,ivborw0kggoaaaa",
"code": "nrew"
}
}3. redis下载
见 redis安装配置教程
二、后端实现
1. 引入依赖
在 pom.xml 文件中引入 easy-captcha 和 redis 相关依赖:
<dependency>
<groupid>com.github.whvcse</groupid>
<artifactid>easy-captcha</artifactid>
<version>1.6.2</version>
</dependency>
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-data-redis</artifactid>
</dependency>2. 添加配置
在application.yml里添加连接redis数据库的配置信息:
spring:
redis:
open: true
database: 1
host: localhost
port: 63793. 后端代码实现
controller:
@restcontroller
public class logincontroller {
@autowired
private redistemplate redistemplate;
@getmapping("/captcha")
public result captcha() {
// 创建一个 speccaptcha 对象,设置验证码图片的宽度、高度和字符长度
speccaptcha speccaptcha = new speccaptcha(130, 48, 4);
// 生成验证码文本,并将其转换为小写(方便后续比较,忽略大小写)
string code = speccaptcha.text().tolowercase();
// 生成一个唯一的 uuid,用于存储验证码到 redis 中
string uuid = idutil.simpleuuid();
// 将验证码文本存入 redis,并设置过期时间为 2 分钟(120 秒)
// 这样可以确保验证码在一定时间后自动失效,避免被恶意利用
this.redistemplate.opsforvalue().set(uuid, code, 120, timeunit.seconds);
// 创建一个 map,用于存储返回给前端的数据
map<string, string> map = new hashmap<string, string>(3);
// 将 uuid 存入 map,前端需要将这个 uuid 一起发送到后端进行验证
map.put("uuid", uuid);
// 将生成的验证码文本存入 map(可选,通常前端不需要知道验证码文本)
map.put("code", code);
// 将验证码图片转换为 base64 字符串,并存入 map
// 前端可以通过这个 base64 字符串生成验证码图片
map.put("captcha", speccaptcha.tobase64());
// 返回 result 对象,其中包含验证码图片的 base64 字符串和 uuid
// result.ok() 表示操作成功,put("data", map) 将 map 数据放入响应中
return result.ok().put("data", map);
}
@postmapping("/login")
public result login(@requestbody loginform loginform, httpsession session){
//验证码校验
string code = (string) this.redistemplate.opsforvalue().get(loginform.getuuid());
//判断验证码是否有效
if(code == null){
return result.error("验证码已过期");
}
//判断验证码是否正确
if(!code.equals(loginform.getcaptcha())){
return result.error("验证码错误");
}
//判断用户名是否正确
querywrapper<user> querywrapper = new querywrapper<>();
querywrapper.eq("username", loginform.getusername());
user user = this.userservice.getone(querywrapper);
if(user == null){
return result.error("用户名错误");
}
//判断密码是否正确
string password = secureutil.sha256(loginform.getpassword());
if(!password.equals(user.getpassword())){
return result.error("密码错误");
}
//验证用户是否可用
if(user.getstatus() == 0) {
return result.error("账号已被锁定,请联系管理员");
}
//登录成功
session.setattribute("user", user);
//创建token
string token = this.jwtutil.createtoken(string.valueof(user.getuserid()));
this.redistemplate.opsforvalue().set("communityuser-"+user.getuserid(), token,jwtutil.getexpire());
map<string,object> map = new hashmap<>();
map.put("token", token);
map.put("expire", jwtutil.getexpire());
logaspect.user = user;
return result.ok().put("data", map);
}
}redistemplate 是 spring data redis 提供的一个高级抽象,封装了 redis 的操作。它支持多种数据结构(如字符串、列表、集合、哈希等),并提供了丰富的操作方法。通过 redistemplate,可以方便地执行 redis 命令,而无需直接使用 redis 的原生客户端。
常用方法:
- opsforvalue():用于操作 redis 中的字符串(
string)数据。 - opsforlist():用于操作 redis 中的列表(
list)数据。 - opsforset():用于操作 redis 中的集合(
set)数据。 - opsforhash():用于操作 redis 中的哈希(
hash)数据。 - opsforzset():用于操作 redis 中的有序集合(
sorted set)数据。
4. 前端代码实现
获取验证码
前端通过调用后端接口获取验证码图片和 uuid。这个 uuid 用于在后端标识验证码的唯一性。
// 获取验证码
getcaptcha() {
getcaptchaimg().then(res => {
this.captchapath = res.data.captcha; // 将验证码图片的 base64 字符串赋值给 captchapath
this.loginform.uuid = res.data.uuid; // 将 uuid 赋值给 loginform 的 uuid 属性
if (process.env.node_env === 'development') {
this.loginform.captcha = res.data.code; // 在开发环境中自动填充验证码(方便测试)
}
});
}显示验证码
前端通过 el-image 组件显示验证码图片,并提供点击刷新功能。
<el-image class="captcha-img" :src="captchapath" <!-- 绑定验证码图片的 base64 字符串 --> @click="getcaptcha()" <!-- 点击图片时重新获取验证码 --> />
3. 提交表单时验证验证码
用户输入验证码后,点击登录按钮提交表单。前端将用户输入的验证码和 uuid 一起发送到后端进行验证。
handlelogin() {
this.$refs.loginform.validate(valid => {
if (valid) {
this.loading = true;
this.$store.dispatch('user/login', this.loginform)
.then(() => {
this.$router.push({ path: this.redirect || '/' }); // 登录成功后跳转
})
.catch(() => {
this.getcaptcha(); // 登录失败,重新获取验证码
this.loading = false;
});
} else {
return false;
}
});
}
到此这篇关于springboot使用 easy-captcha 实现验证码登录功能的文章就介绍到这了,更多相关springboot验证码登录内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论