【若依】3、验证码(kaptcha)
AjaxResult
:出参;code
(状态码)、msg
(返回内容)、data
(数据对象)。
验证码引用了一个开源项目:
GitHub - penggle/kaptcha: kaptcha - A kaptcha generation engine.
captchaEnabled
:是否开启验证码功能;对应的数据库中表:sys_config,此配置会缓存redis中。
验证码图片返回的格式是:base64编码,这样的优势是还可以同时返回其他数据。
captchaType
:验证码类型 math 数组计算 char 字符;可在 application.yml 中配置。
验证码配置
- 关于验证码在session中的存储问题
tienchin-framework/src/main/java/top/yueyazhui/tienchin/framework/config/CaptchaConfig.java
char:top.yueyazhui.tienchin.framework.config.CaptchaConfig#getKaptchaBean
math:top.yueyazhui.tienchin.framework.config.CaptchaConfig#getKaptchaBeanMath
其中有一项配置可以忽略,因为这项配置不会生效:
1
2
// KAPTCHA_SESSION_KEY
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
1
2
// KAPTCHA_SESSION_KEY
properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
此项配置的作用是:生成验证码的时候,会自动将验证码文本存入session中。 如果使用kaptcha提供的KaptchaServlet这项配置才可以生效;如果是自己写的Controller不会生效,如有需要,自己写的Controller需要自己把验证码文本存入session中; 测试代码地址: yueyazhui/ruoyi_kaptcha
- 验证码文本生成器
在math中使用了自己提供的验证码文本生成器
tienchin-framework/src/main/java/top/yueyazhui/tienchin/framework/config/KaptchaTextCreator.java
验证码的校验
入口:
tienchin-admin/src/main/java/top/yueyazhui/tienchin/web/controller/system/SysLoginController.java
top.yueyazhui.tienchin.web.controller.system.SysLoginController#login
校验方法:
tienchin-framework/src/main/java/top/yueyazhui/tienchin/framework/web/service/SysLoginService.java
top.yueyazhui.tienchin.framework.web.service.SysLoginService#validateCaptcha
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* 校验验证码
*
* @param username 用户名
* @param code 验证码
* @param uuid 唯一标识
* @return 结果
*/
public void validateCaptcha(String username, String code, String uuid) {
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
// 获取redis中保存的验证码文本
String captcha = redisCache.getCacheObject(verifyKey);
// 删除redis中保存的验证码文本
redisCache.deleteObject(verifyKey);
if (captcha == null) {
// redis中不存在验证码(超过两分钟,验证码过期被自动删除)
// 开启一个异步任务去写日志
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
throw new CaptchaExpireException();
}
if (!code.equalsIgnoreCase(captcha)) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
throw new CaptchaException();
}
}