简介
-
本教程利用hutool工具包简单粗暴的实现验证码登录,验证码功能位于cn.hutool.captcha包中,核心接口为ICaptcha,此接口定义了以下方法:
createCode
创建验证码,实现类需同时生成随机验证码字符串和验证码图片
getCode
获取验证码的文字内容
verify
验证验证码是否正确,建议忽略大小写
write
将验证码写出到目标流中 -
支持前后端分离
-
支持自定义验证码
-
支持运算验证码
1. 依赖
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- hutool工具包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0</version>
</dependency>
2. 封装验证码工具类
CaptchaUtils
/**
* 生成及校验图片验证码
*
* @author ding
*/
public class CaptchaUtils {
/**
* 模拟redis存储验证码,生成环境建议使用redis存储验证码,设置一个有效期,如5分钟
*/
private static final HashMap<String, String> CODE_MAP = new LinkedHashMap<>();
/**
* CircleCaptcha 圆圈干扰验证码
* (200, 100, 5, 20)定义图形验证码的长、宽、验证码字符数、干扰元素个数
*
* @param uuid 由web端生成一个随机uuid,登录时需将uuid和验证码一起提交,前后端分离时,可通过uuid确认验证码来源
* @param response 响应体
*/
public static void getCircleCaptcha(String uuid, HttpServletResponse response) throws IOException {
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100, 5, 20);
CODE_MAP.put(uuid, lineCaptcha.getCode());
writeResp(lineCaptcha, response);
}
/**
* ShearCaptcha 扭曲干扰验证码
* (200, 100, 4, 4)定义图形验证码的长、宽、验证码字符数、干扰线宽度
*
* @param uuid 由web端生成一个随机uuid,登录时需将uuid和验证码一起提交,前后端分离时,可通过uuid确认验证码来源
* @param response 响应体
*/
public static void getShearCaptcha(String uuid, HttpServletResponse response) throws IOException {
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 100, 4, 4);
CODE_MAP.put(uuid, captcha.getCode());
writeResp(captcha, response);
}
/**
* 自定义验证码
* 加减验证码
*
* @param uuid 由web端生成一个随机uuid,登录时需将uuid和验证码一起提交,前后端分离时,可通过uuid确认验证码来源
* @param response 响应体
*/
public static void getMathShearCaptcha(String uuid, HttpServletResponse response) throws IOException {
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 45, 4, 4);
// 自定义验证码内容为四则运算方式
captcha.setGenerator(new MathGenerator());
CODE_MAP.put(uuid, captcha.getCode());
writeResp(captcha, response);
}
/**
* 验证码校验
*
* @param uuid 获取验证码时提交的uuid
* @param code 验证码
*/
public static boolean verify(String uuid, String code) {
boolean b = Optional
.ofNullable(CODE_MAP.get(uuid))
.stream()
.anyMatch(c -> c.equals(code));
if (b) {
CODE_MAP.remove(uuid);
}
return b;
}
/**
* http图片响应
*/
private static void writeResp(AbstractCaptcha abstractCaptcha, HttpServletResponse response) throws IOException {
ServletOutputStream out = null;
try {
out = response.getOutputStream();
abstractCaptcha.write(out);
} finally {
if (Objects.nonNull(out)) {
out.close();
}
}
}
}
- 这里测试用了map存储验证码,生产环境换成redis即可
- 之所以由web端生成一个随机
uuid
,是因为在前后端分离时,是无法使用session
的,为了确保来源需前端主动发送一个标识码过来,第二步登录时可通过uuid
确认验证码来源。
3. 实战
- 编写测试接口
IndexController
/**
* @author ding
*/
@RestController
public class IndexController {
/**
* 获取验证码
*/
@GetMapping("/getCaptcha")
public void getCaptcha(String uuid, HttpServletResponse response) throws IOException {
CaptchaUtils.getCircleCaptcha(uuid, response);
}
/**
* 模拟登录校验
*/
@GetMapping("/login")
public boolean login(String uuid, String code, String username, String password) {
return CaptchaUtils.verify(uuid, code);
}
}
- 这里使用postman测试,也可直接浏览器测试
- 第一步获取验证码,参数
uuid
输入任意即可,生成环境下web端需保证uuid
的随机性
- 第二步模拟登录 参数
uuid
需和第一步的uuid
保持一致
6. 源码分享
- Springboot、SpringCloud各种常用框架使用案例,完善的文档,致力于让开发者快速搭建基础环境并让应用跑起来,并提供丰富的使用示例供使用者参考,快速上手。
- 项目源码github地址
- 项目源码国内gitee地址