From fa3b642d63de035b17f7379c54e7217b49a85093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Sun, 17 Apr 2022 21:51:55 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E7=9B=B8=E5=85=B3=E9=83=A8=E5=88=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruoyi/auth/service/SysLoginService.java | 92 ++++++++----------- .../ruoyi/common/core/enums/LoginType.java | 39 ++++++++ 2 files changed, 79 insertions(+), 52 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java diff --git a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java index d1262749..5b3346df 100644 --- a/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java +++ b/ruoyi-auth/src/main/java/com/ruoyi/auth/service/SysLoginService.java @@ -7,6 +7,7 @@ import com.ruoyi.auth.form.RegisterBody; import com.ruoyi.common.core.constant.CacheConstants; import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.enums.DeviceType; +import com.ruoyi.common.core.enums.LoginType; import com.ruoyi.common.core.enums.UserType; import com.ruoyi.common.core.exception.user.UserException; import com.ruoyi.common.core.utils.MessageUtils; @@ -24,6 +25,7 @@ import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.stereotype.Service; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; /** * 登录校验方法 @@ -44,31 +46,7 @@ public class SysLoginService { public String login(String username, String password) { LoginUser userInfo = remoteUserService.getUserInfo(username); - // 获取用户登录错误次数(可自定义限制策略 例如: key + username + ip) - Integer errorNumber = RedisUtils.getCacheObject(CacheConstants.LOGIN_ERROR + username); - // 锁定时间内登录 则踢出 - if (ObjectUtil.isNotNull(errorNumber) && errorNumber.equals(CacheConstants.LOGIN_ERROR_NUMBER)) { - recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed", CacheConstants.LOGIN_ERROR_LIMIT_TIME)); - throw new UserException("user.password.retry.limit.exceed", CacheConstants.LOGIN_ERROR_LIMIT_TIME); - } - - if (!BCrypt.checkpw(password, userInfo.getPassword())) { - // 是否第一次 - errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1; - // 达到规定错误次数 则锁定登录 - if (errorNumber.equals(CacheConstants.LOGIN_ERROR_NUMBER)) { - RedisUtils.setCacheObject(CacheConstants.LOGIN_ERROR + username, errorNumber, CacheConstants.LOGIN_ERROR_LIMIT_TIME, TimeUnit.MINUTES); - recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.exceed", CacheConstants.LOGIN_ERROR_LIMIT_TIME)); - throw new UserException("user.password.retry.limit.exceed", CacheConstants.LOGIN_ERROR_LIMIT_TIME); - } else { - // 未达到规定错误次数 则递增 - RedisUtils.setCacheObject(CacheConstants.LOGIN_ERROR + username, errorNumber); - recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.retry.limit.count", errorNumber)); - throw new UserException("user.password.retry.limit.count", errorNumber); - } - } - // 登录成功 清空错误次数 - RedisUtils.deleteObject(CacheConstants.LOGIN_ERROR + username); + checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, userInfo.getPassword())); // 获取登录token LoginHelper.loginByDevice(userInfo, DeviceType.PC); @@ -80,33 +58,7 @@ public class SysLoginService { // 通过手机号查找用户 LoginUser userInfo = remoteUserService.getUserInfoByPhonenumber(phonenumber); - // 获取用户登录错误次数(可自定义限制策略 例如: key + username + ip) - Integer errorNumber = RedisUtils.getCacheObject(CacheConstants.LOGIN_ERROR + userInfo.getUsername()); - // 锁定时间内登录 则踢出 - if (ObjectUtil.isNotNull(errorNumber) && errorNumber.equals(CacheConstants.LOGIN_ERROR_NUMBER)) { - recordLogininfor(userInfo.getUsername(), Constants.LOGIN_FAIL, MessageUtils.message("sms.code.retry.limit.exceed", CacheConstants.LOGIN_ERROR_LIMIT_TIME)); - throw new UserException("sms.code.retry.limit.exceed", CacheConstants.LOGIN_ERROR_LIMIT_TIME); - } - - if (!validateSmsCode(phonenumber, smsCode)) { - // 是否第一次 - errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1; - // 达到规定错误次数 则锁定登录 - if (errorNumber.equals(CacheConstants.LOGIN_ERROR_NUMBER)) { - RedisUtils.setCacheObject(CacheConstants.LOGIN_ERROR + userInfo.getUsername(), errorNumber, CacheConstants.LOGIN_ERROR_LIMIT_TIME, TimeUnit.MINUTES); - recordLogininfor(userInfo.getUsername(), Constants.LOGIN_FAIL, MessageUtils.message("sms.code.retry.limit.exceed", CacheConstants.LOGIN_ERROR_LIMIT_TIME)); - throw new UserException("sms.code.retry.limit.exceed", CacheConstants.LOGIN_ERROR_LIMIT_TIME); - } else { - // 未达到规定错误次数 则递增 - RedisUtils.setCacheObject(CacheConstants.LOGIN_ERROR + userInfo.getUsername(), errorNumber); - recordLogininfor(userInfo.getUsername(), Constants.LOGIN_FAIL, MessageUtils.message("sms.code.retry.limit.count", errorNumber)); - throw new UserException("sms.code.retry.limit.count", errorNumber); - } - } - - // 登录成功 清空错误次数 - RedisUtils.deleteObject(CacheConstants.LOGIN_ERROR + userInfo.getUsername()); - + checkLogin(LoginType.SMS, userInfo.getUsername(), () -> !validateSmsCode(phonenumber, smsCode)); // 生成token LoginHelper.loginByDevice(userInfo, DeviceType.APP); @@ -181,4 +133,40 @@ public class SysLoginService { // todo 此处使用手机号查询redis验证码与参数验证码是否一致 用户自行实现 return true; } + + /** + * 登录校验 + */ + private void checkLogin(LoginType loginType, String username, Supplier supplier) { + String errorKey = CacheConstants.LOGIN_ERROR + username; + Integer errorLimitTime = CacheConstants.LOGIN_ERROR_LIMIT_TIME; + Integer setErrorNumber = CacheConstants.LOGIN_ERROR_NUMBER; + String loginFail = Constants.LOGIN_FAIL; + + // 获取用户登录错误次数(可自定义限制策略 例如: key + username + ip) + Integer errorNumber = RedisUtils.getCacheObject(errorKey); + // 锁定时间内登录 则踢出 + if (ObjectUtil.isNotNull(errorNumber) && errorNumber.equals(setErrorNumber)) { + recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), errorLimitTime)); + throw new UserException(loginType.getRetryLimitExceed(), errorLimitTime); + } + + if (supplier.get()) { + // 是否第一次 + errorNumber = ObjectUtil.isNull(errorNumber) ? 1 : errorNumber + 1; + // 达到规定错误次数 则锁定登录 + if (errorNumber.equals(setErrorNumber)) { + RedisUtils.setCacheObject(errorKey, errorNumber, errorLimitTime, TimeUnit.MINUTES); + recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitExceed(), errorLimitTime)); + throw new UserException(loginType.getRetryLimitExceed(), errorLimitTime); + } else { + // 未达到规定错误次数 则递增 + RedisUtils.setCacheObject(errorKey, errorNumber); + recordLogininfor(username, loginFail, MessageUtils.message(loginType.getRetryLimitCount(), errorNumber)); + throw new UserException(loginType.getRetryLimitCount(), errorNumber); + } + } + // 登录成功 清空错误次数 + RedisUtils.deleteObject(errorKey); + } } diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java new file mode 100644 index 00000000..fcd48dfb --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/LoginType.java @@ -0,0 +1,39 @@ +package com.ruoyi.common.core.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 登录类型 + * + * @author Lion Li + */ +@Getter +@AllArgsConstructor +public enum LoginType { + + /** + * 密码登录 + */ + PASSWORD("user.password.retry.limit.exceed", "user.password.retry.limit.count"), + + /** + * 短信登录 + */ + SMS("sms.code.retry.limit.exceed", "sms.code.retry.limit.count"), + + /** + * 小程序登录 + */ + XCX("", ""); + + /** + * 登录重试超出限制提示 + */ + final String retryLimitExceed; + + /** + * 登录重试限制计数提示 + */ + final String retryLimitCount; +}