|
@@ -74,11 +74,6 @@ public class SysAuthServiceImpl implements SysAuthService {
|
|
|
private String REDIS_LOGIN_TOKEN_PREFIX;
|
|
|
@Value("${spring.application.name}")
|
|
|
private String APPLICATION_NAME;
|
|
|
- private String redisKeyOfLogin = APPLICATION_NAME + "-sms-login";
|
|
|
- private String redisKeyOfRegister = APPLICATION_NAME + "-sms-register";
|
|
|
- private String redisKeyOfLoginFail = APPLICATION_NAME + "-login-error";
|
|
|
- private String redisKeyOfRegisterFail = APPLICATION_NAME + "-register-error";
|
|
|
- private String redisKeyOfCaptchaRequired = APPLICATION_NAME + "-" + httpRequestUtil.getKaptchaKey() + "-required";
|
|
|
|
|
|
@Override
|
|
|
public void renderCaptcha(HttpServletResponse response) throws IOException {
|
|
@@ -108,25 +103,37 @@ public class SysAuthServiceImpl implements SysAuthService {
|
|
|
responseOutputStream.close();
|
|
|
}
|
|
|
|
|
|
+ // 判断是否需验证码登录状态
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> checkCaptchaRequired(String username) {
|
|
|
+ if (StrUtil.isEmpty(username)) throw new CustException("username 不能为空");
|
|
|
+ Boolean currentCaptchaRequired = captchaUtil.isCaptchaRequired(APPLICATION_NAME + "-login-required-captcha-" + username, 3);
|
|
|
+ return Map.of("is_captcha_required", currentCaptchaRequired);
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public List<SysMobileArea> getMobileAreaList(SysMobileArea sysMobileArea) {
|
|
|
return sysMobileAreaDao.selectMobileAreaList(sysMobileArea);
|
|
|
}
|
|
|
|
|
|
- // [方法] 登录失败 (errMsg: 错误提示文本, username: 用户名, intercept: 是否拦截)
|
|
|
+ // [方法] 登录失败 (通用) (errMsg: 错误提示文本, username: 用户名, intercept: 是否拦截)
|
|
|
private void loginFail(String errMsg, String username, Boolean isIntercept) {
|
|
|
|
|
|
- // 输入错误时,计数器叠加,并且设置重置时间 (会一直叠加)
|
|
|
- Integer currentErrCount;
|
|
|
- Object captchaRequired = redisUtil.getCacheObject(redisKeyOfCaptchaRequired);
|
|
|
- currentErrCount = (captchaRequired == null) ? 1 : (Convert.toInt(captchaRequired) + 1);
|
|
|
- redisUtil.setCacheObject(redisKeyOfCaptchaRequired, currentErrCount, 1, TimeUnit.MINUTES);
|
|
|
+ // 验证码是否必填
|
|
|
+ Boolean currentCaptchaRequired = captchaUtil.isCaptchaRequired(APPLICATION_NAME + "-login-required-captcha-" + username, 3);
|
|
|
+ System.out.println("(loginFailByUsername) currentCaptchaRequired = " + currentCaptchaRequired);
|
|
|
|
|
|
// 删除图形验证码
|
|
|
redisUtil.delete(httpRequestUtil.getKaptchaKey());
|
|
|
// 添加登录错误的冻结标记
|
|
|
- if (isIntercept) lockStatusUtil.setLockStatus(redisKeyOfLoginFail, username);
|
|
|
- throw new CustException(errMsg, ResultEnum.INVALID_CREDENTIALS.getCode());
|
|
|
+ if (isIntercept) lockStatusUtil.setLockStatus(APPLICATION_NAME + "-login-error", username);
|
|
|
+
|
|
|
+ if (currentCaptchaRequired) {
|
|
|
+ throw new CustException(errMsg, ResultEnum.INVALID_CREDENTIALS.getCode(), Map.of("is_captcha_required", true));
|
|
|
+ } else {
|
|
|
+ throw new CustException(errMsg, ResultEnum.INVALID_CREDENTIALS.getCode());
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
// [方法] 登录成功
|
|
@@ -190,6 +197,16 @@ public class SysAuthServiceImpl implements SysAuthService {
|
|
|
return sysUserInfo;
|
|
|
}
|
|
|
|
|
|
+ private void setLoginRequired(String key) {
|
|
|
+ Object captchaValue = redisUtil.getCacheObject(APPLICATION_NAME + "-login-required-captcha-" + key);
|
|
|
+ Integer currentErrCount = (captchaValue == null) ? 1 : (Convert.toInt(captchaValue) + 1);
|
|
|
+ redisUtil.setCacheObject(APPLICATION_NAME + "-login-required-captcha-" + key, currentErrCount, 1, TimeUnit.MINUTES);
|
|
|
+ System.out.println("currentErrCount: " + currentErrCount);
|
|
|
+ }
|
|
|
+ private void cleanLoginRequired(String key) {
|
|
|
+ redisUtil.delete(APPLICATION_NAME + "-login-required-captcha-" + key);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 登录 (用户名)
|
|
|
*/
|
|
@@ -202,36 +219,36 @@ public class SysAuthServiceImpl implements SysAuthService {
|
|
|
String captcha = sysAuth.getCaptcha();
|
|
|
|
|
|
// 判断是否处于登录错误的冻结状态 (2分钟内错误5次,则出现冻结提示)
|
|
|
- lockStatusUtil.checkLockStatus(redisKeyOfLoginFail, username);
|
|
|
+ lockStatusUtil.checkLockStatus(APPLICATION_NAME + "-login-error", username);
|
|
|
|
|
|
- // 判断是否需要输入验证码
|
|
|
+ // -- 判断是否需要输入验证码 ----------------------------------------------------
|
|
|
// - 当输错 3 次密码时,需要输入验证码
|
|
|
// - 当输错后 1 分钟后重置
|
|
|
- Boolean isCaptchaRequired = captchaUtil.isCaptchaRequired(redisKeyOfCaptchaRequired, 3);
|
|
|
+ Boolean isCaptchaRequired = captchaUtil.isCaptchaRequired(APPLICATION_NAME + "-login-required-captcha-" + username, 3);
|
|
|
if (isCaptchaRequired) {
|
|
|
- if (StrUtil.isEmpty(captcha)) {
|
|
|
- loginFail("验证码不能为空", username, false);
|
|
|
- return null;
|
|
|
- }
|
|
|
- if (!captchaUtil.isCaptchaValid(captcha, httpRequestUtil.getKaptchaKey())) {
|
|
|
- loginFail("验证码错误", username, false);
|
|
|
- return null;
|
|
|
- }
|
|
|
+ Boolean isCaptchaEmpty = StrUtil.isEmpty(captcha);
|
|
|
+ Boolean isCpatchaValid = (captchaUtil.isCaptchaValid(captcha, httpRequestUtil.getKaptchaKey()));
|
|
|
+ if (isCaptchaEmpty) { loginFail("验证码不能为空", username, false); return null; }
|
|
|
+ if (!isCpatchaValid) { loginFail("验证码错误", username, false); return null; }
|
|
|
}
|
|
|
+ // --------------------------------------------------------------------------
|
|
|
|
|
|
// [Method] 判断 用户 是否存在 && 密码是否正确
|
|
|
SysUser sysUser = sysUserDao.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
|
|
|
if (sysUser == null) {
|
|
|
// [登录失败] 用户不存在
|
|
|
+ setLoginRequired(username); // 输入错误时,计数器叠加,并且设置重置时间 (会一直叠加,直到重置 或 登录成功)
|
|
|
loginFail("用户名或密码错误", username, true);
|
|
|
return null;
|
|
|
} else {
|
|
|
// [登录失败] 密码不正确
|
|
|
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
|
|
|
if (!encoder.matches(password, sysUser.getPassword())) {
|
|
|
+ setLoginRequired(username); // 输入错误时,计数器叠加,并且设置重置时间 (会一直叠加,直到重置 或 登录成功)
|
|
|
loginFail("用户名或密码错误", username, true);
|
|
|
}
|
|
|
// [登录成功]
|
|
|
+ cleanLoginRequired(username);
|
|
|
return loginSuccess(sysUser.getId(), sysAuth.getIs_remember());
|
|
|
}
|
|
|
|
|
@@ -249,10 +266,10 @@ public class SysAuthServiceImpl implements SysAuthService {
|
|
|
Integer phoneValidCode = sysAuthPhone.getPhone_valid_code();
|
|
|
|
|
|
// 判断是否处于登录错误的冻结状态 (2分钟内错误5次,则出现冻结提示)
|
|
|
- lockStatusUtil.checkLockStatus(redisKeyOfLoginFail, phone);
|
|
|
+ lockStatusUtil.checkLockStatus(APPLICATION_NAME + "-login-error", phone);
|
|
|
|
|
|
// 判断短信验证码是否正确
|
|
|
- String redisKey = redisKeyOfLogin + "-" + phone;
|
|
|
+ String redisKey = APPLICATION_NAME + "-sms-login" + "-" + phone;
|
|
|
Integer smsCode = redisUtil.getCacheObject(redisKey);
|
|
|
// 判断是否发送验证码
|
|
|
if ("false".equals(SMS_DEBUG) && smsCode == null) throw new CustException("请先发送验证码");
|
|
@@ -295,8 +312,8 @@ public class SysAuthServiceImpl implements SysAuthService {
|
|
|
Integer phoneValidCode = sysUserDTO.getPhone_valid_code();
|
|
|
|
|
|
// 判断是否处于登录错误的冻结状态 (2分钟内错误5次,则出现冻结提示)
|
|
|
- lockStatusUtil.checkLockStatus(redisKeyOfRegisterFail, username);
|
|
|
- lockStatusUtil.checkLockStatus(redisKeyOfRegisterFail, phone);
|
|
|
+ lockStatusUtil.checkLockStatus(APPLICATION_NAME + "-register-error", username);
|
|
|
+ lockStatusUtil.checkLockStatus(APPLICATION_NAME + "-register-error", phone);
|
|
|
|
|
|
// 判断图形验证码是否正确
|
|
|
if (!captchaUtil.isCaptchaValid(captcha, httpRequestUtil.getKaptchaKey())) {
|
|
@@ -309,7 +326,7 @@ public class SysAuthServiceImpl implements SysAuthService {
|
|
|
if (sysUser1 != null) throw new CustException("用户名 (" + username + ") 已被注册");
|
|
|
|
|
|
// 判断短信验证码是否正确
|
|
|
- String redisKey = redisKeyOfLogin + "-" + phone;
|
|
|
+ String redisKey = APPLICATION_NAME + "-sms-login" + "-" + phone;
|
|
|
Integer smsCode = redisUtil.getCacheObject(redisKey);
|
|
|
// 判断是否发送验证码
|
|
|
if ("false".equals(SMS_DEBUG) && smsCode == null) throw new CustException("请先发送验证码");
|