SpringBoot实战:验证码登录Captcha简单粗暴(附git源码)
文章目录
- 简介
-
- 1. 依赖
- 2. 封装验证码工具类
- 3. 实战
- 6. 源码分享
简介
-
本教程利用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> <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 */@RestControllerpublic 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地址