SpringBoot3整合Hutool-captcha实现图形验证码
验证码需求分析:
1. 生成验证码,点击图片可进行刷新
2. 输入验证码,点击提交,验证用户输入验证码是否正确
项目创建
首先创建项目这里使用的Spring boot 3 + JDK17,并引入相关依赖
pom.xml
<properties> <java.version>17</java.version> <hutool.version>5.8.26</hutool.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-captcha</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-bom</artifactId> <version>${hutool.version}</version> <type>pom</type> <!-- 注意这里是import --> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
import方式的使用说明
如果你想像Spring-Boot一样引入Hutool,再由子模块决定用到哪些模块,你可以在父模块中加入:
<dependencyManagement> <dependencies> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-bom</artifactId> <version>${hutool.version}</version> <type>pom</type> <!-- 注意这里是import --> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
在子模块中就可以引入自己需要的模块了:
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-captcha</artifactId> </dependency>
使用import的方式,只会引入hutool-bom内的dependencyManagement的配置,其它配置在这个引用方式下完全不起作用。
exclude方式
如果你引入的模块比较多,但是某几个模块没用,你可以:
<dependencies> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-bom</artifactId> <version>${hutool.version}</version> <!-- 加不加这句都能跑,区别只有是否告警 --> <type>pom</type> <exclusions> <exclusion> <groupId>cn.hutool</groupId> <artifactId>hutool-system</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
这个配置会传递依赖hutool-bom内所有dependencies的内容,当前hutool-bom内的dependencies全部设置了version,就意味着在maven resolve的时候hutool-bom内就算存在dependencyManagement也不会产生任何作用。
定义接口:
1. 生成验证码,并返回
2. 校验验证码是否正确
接口定义
1. 生成验证码 [URL] GET /captcha/getCaptcha [请求参数] [响应] { "uuid": "fc2b40825f20470bb4f5d9868b33856f", "img": "data:image/png;base64,issaxxxxxxxxgg==" } uuid 是为了方便在真实项目使用中做区分
2. 校验验证码是否正确 [URL] POST /captcha/check [请求参数] {"uuid":"43b4b30bf1134e9f8430507b7babd620","code":""} [响应] { true } 根据用户输入的验证码,校验验证码是否正确,校验成功,返回true;校验失败,返回false
定义 CaptchaController
@Slf4j @RestController @RequestMapping("/captcha") @AllArgsConstructor public class CaptchaController { private final SysCaptchaService sysCaptchaService; /** * 生成验证码 */ @GetMapping("/getCaptcha") public CaptchaResult getCaptcha(HttpSession session) { return sysCaptchaService.getCaptcha(session); } /** * 验证码校验 * * @param param 验证码参数 */ @PostMapping("/check") public boolean checkCaptcha(@RequestBody CaptchaValidateParam param, HttpSession session) { String uuid = param.getUuid(); String captcha = param.getCode(); if (StrUtil.isEmpty(uuid) || StrUtil.isEmpty(captcha)) { log.error("验证码参数不能为空"); return false; } log.info("接收到验证码: uuId:{}, 验证码:{}", uuid, captcha); // 参数校验 return sysCaptchaService.validate(uuid, captcha, session); } }
由于当用户输入验证码时,我们需要进行校验,因此,我们需要对生成的验证码进行存储,同时,需要存储验证码的生成时间,以便判断验证码是否超时
public class Constants { public static final String CAPTCHA_CODE = "code"; public static final String CAPTCHA_UUID = "uuid"; }
- SysCaptchaService
public interface SysCaptchaService { /** * 获取验证码 * * @param session * @return */ CaptchaResult getCaptcha(HttpSession session); /** * 验证码效验 * * @param uuid * @param code * @param session * @return */ boolean validate(String uuid, String code, HttpSession session); }
- SysCaptchaServiceImpl
@Service @RequiredArgsConstructor @Slf4j public class SysCaptchaServiceImpl implements SysCaptchaService { private final CaptchaProperties captchaProperties; private final CodeGenerator codeGenerator; private final Font captchaFont; @Override public CaptchaResult getCaptcha(HttpSession session) { String captchaType = captchaProperties.getType(); int width = captchaProperties.getWidth(); int height = captchaProperties.getHeight(); int interfereCount = captchaProperties.getInterfereCount(); int codeLength = captchaProperties.getCode().getLength(); AbstractCaptcha captcha; if (CaptchaTypeEnums.CIRCLE.name().equalsIgnoreCase(captchaType)) { captcha = CaptchaUtil.createCircleCaptcha(width, height, codeLength, interfereCount); } else if (CaptchaTypeEnums.GIF.name().equalsIgnoreCase(captchaType)) { captcha = CaptchaUtil.createGifCaptcha(width, height, codeLength); } else if (CaptchaTypeEnums.LINE.name().equalsIgnoreCase(captchaType)) { captcha = CaptchaUtil.createLineCaptcha(width, height, codeLength, interfereCount); } else if (CaptchaTypeEnums.SHEAR.name().equalsIgnoreCase(captchaType)) { captcha = CaptchaUtil.createShearCaptcha(width, height, codeLength, interfereCount); } else { throw new IllegalArgumentException("Invalid captcha type: " + captchaType); } captcha.setGenerator(codeGenerator); captcha.setTextAlpha(captchaProperties.getTextAlpha()); captcha.setFont(captchaFont); String code = captcha.getCode(); String imageBase64Data = captcha.getImageBase64Data(); // 验证码文本缓存至Redis,用于登录校验 String uuid = IdUtil.fastSimpleUUID(); session.setAttribute(Constants.CAPTCHA_CODE, code); session.setAttribute(Constants.CAPTCHA_UUID, uuid); return CaptchaResult.builder().img(imageBase64Data).uuid(uuid).build(); } @Override public boolean validate(String uuid, String code, HttpSession session) { // session中获取验证码 String captchaCode = (String) session.getAttribute(Constants.CAPTCHA_CODE); return codeGenerator.verify(captchaCode, code); }
将用户输入的验证码与存储在 session 中的验证码进行对比,判断其是否相同,若相同且在1min内,则验证成功
前端代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } #inputCaptcha { height: 30px; vertical-align: middle; } #verificationCodeImg { vertical-align: middle; } #checkCaptcha { height: 40px; width: 100px; border: 1px solid #000; border-radius: 5px; margin-left: 10px; vertical-align: middle; } </style> </head> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script> <body> <div id="app"> <h1>{{ message }}</h1> <input type="text" v-model="inputCaptcha" id="inputCaptcha"> <img id="verificationCodeImg" :src="captchaData.img" alt="验证码" @click="refreshCaptcha" title="看不清?换一张"/> <input type="button" value="提交" id="checkCaptcha" @click="checkCaptcha"> </div> <script type="module"> import {createApp, ref, onMounted} from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js' createApp({ setup() { const message = ref('验证码校验') const inputCaptcha = ref('') const captchaData = ref({ img: '', uuid: '' }) const refreshCaptcha = () => { $.ajax({ url: '/captcha/getCaptcha', type: 'GET', success: function (data) { captchaData.value = data } }) } const checkCaptcha = () => { const dataFrom = { uuid: captchaData.value.uuid, code: inputCaptcha.value } $.ajax({ url: '/captcha/check', type: 'POST', headers: { 'Content-Type': 'application/json' }, data: JSON.stringify(dataFrom), success: function (data) { if (data) { alert('验证码正确') refreshCaptcha() } else { alert('验证码错误') refreshCaptcha() } } }) } // 页面加载完成后,刷新验证码 onMounted(() => { refreshCaptcha() }) return { message, captchaData, inputCaptcha, refreshCaptcha, checkCaptcha } } }).mount('#app') </script> </body> </html>
验证成功:
验证失败:
为让验证码有多样性,这里将验证的生成放入了application.yml
配置文件中,内容如下:
# 验证码配置 captcha: # 验证码类型 circle-圆圈干扰验证码|gif-Gif验证码|line-干扰线验证码|shear-扭曲干扰验证码 type: circle # 验证码宽度 width: 130 # 验证码高度 height: 48 # 验证码干扰元素个数 interfere-count: 2 # 文本透明度(0.0-1.0) text-alpha: 0.8 # 验证码字符配置 code: # 验证码字符类型 math-算术|random-随机字符 type: math # 验证码字符长度,type=算术时,表示运算位数(1:个位数运算 2:十位数运算);type=随机字符时,表示字符个数 length: 1 # 验证码字体 font: # 字体名称 Dialog|DialogInput|Monospaced|Serif|SansSerif name: SansSerif # 字体样式 0-普通|1-粗体|2-斜体 weight: 1 # 字体大小 size: 20 # 验证码有效期(秒) expire-seconds: 120
以上就是SpringBoot3整合Hutool-captcha实现图形验证码的详细内容,更多关于SpringBoot3 Hutool-captcha验证码的资料请关注脚本之家其它相关文章!
相关文章
阿里巴巴 Sentinel + InfluxDB + Chronograf 实现监控大屏
这篇文章主要介绍了阿里巴巴 Sentinel + InfluxDB + Chronograf 实现监控大屏,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下2019-09-09springboot2.5.2与 flowable6.6.0整合流程引擎应用分析
这篇文章主要介绍了springboot2.5.2与 flowable6.6.0整合流程引擎应用分析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2021-07-07
最新评论