新增登录页图形验证码功能,支持通过Redis全局配置控制验证码的启用状态,优化登录流程以提升用户体验。新增相关API接口和前端配置项,确保验证码逻辑与后端同步。

This commit is contained in:
geht
2026-04-20 14:21:36 +08:00
parent 7a648b20be
commit 73426a7af3
23 changed files with 450 additions and 103 deletions

View File

@@ -12,6 +12,7 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CacheConstant;
@@ -737,6 +738,46 @@ public class LoginController {
}
return Result.ok();
}
/**
* 登录页是否启用图形验证码(未登录可访问)。优先 Redis 全局配置(与侧边栏项目配置同步),否则沿用 jeecg.firewall.enable-login-captcha
*/
@IgnoreAuth
@GetMapping("/loginCaptchaConfig")
@Operation(summary = "登录页是否启用图形验证码")
public Result<Boolean> loginCaptchaConfig() {
return Result.OK(isLoginCaptchaRequired());
}
/**
* 保存登录页图形验证码开关(写入 Redis全站生效需权限 system:project:setting:loginCaptcha
*/
@PostMapping("/setLoginCaptchaConfig")
@Operation(summary = "保存登录页图形验证码开关")
@RequiresPermissions("system:project:setting:loginCaptcha")
public Result<String> setLoginCaptchaConfig(@RequestBody JSONObject body) {
Boolean enabled = body.getBoolean("enabled");
if (enabled == null) {
return Result.error("参数 enabled 不能为空");
}
redisUtil.set(CommonConstant.SYS_LOGIN_CAPTCHA_ENABLED, enabled.toString());
baseCommonService.addLog("保存登录验证码开关: " + enabled, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_3);
return Result.OK("保存成功");
}
/**
* 是否需要在登录时校验图形验证码Redis 覆盖 &gt; firewall 配置)
*/
private boolean isLoginCaptchaRequired() {
Object v = redisUtil.get(CommonConstant.SYS_LOGIN_CAPTCHA_ENABLED);
if (v != null) {
return Boolean.parseBoolean(v.toString());
}
return jeecgBaseConfig.getFirewall() == null
|| jeecgBaseConfig.getFirewall().getEnableLoginCaptcha() == null
|| Boolean.TRUE.equals(jeecgBaseConfig.getFirewall().getEnableLoginCaptcha());
}
/**
* 登录二维码
*/
@@ -917,9 +958,9 @@ public class LoginController {
* 校验验证码工具方法校验失败直接返回Result校验通过返回realKey
*/
private String validateCaptcha(SysLoginModel sysLoginModel, Result<JSONObject> result) {
// 判断是否启用登录验证码校验
if (jeecgBaseConfig.getFirewall() != null && Boolean.FALSE.equals(jeecgBaseConfig.getFirewall().getEnableLoginCaptcha())) {
log.warn("关闭登录验证码校验,跳过验证码校验!");
// 是否启用登录验证码(含 Redis 全局开关与 firewall 配置)
if (!isLoginCaptchaRequired()) {
log.warn("关闭登录验证码校验Redis 全局或 firewall,跳过验证码校验!");
return "LoginWithoutVerifyCode";
}

View File

@@ -52,6 +52,11 @@ public class SysCheckRuleServiceImpl extends ServiceImpl<SysCheckRuleMapper, Sys
for (int i = 0; i < rules.size(); i++) {
JSONObject result = new JSONObject();
JSONObject rule = rules.getJSONObject(i);
// 全局规则可选「不执行」priority 为 2 时跳过本条(仅保留配置,不参与校验)
String priority = rule.getString("priority");
if ("2".equals(priority)) {
continue;
}
// 位数
String digits = rule.getString("digits");
result.put("digits", digits);