|
@@ -83,7 +83,7 @@ public class AdminAuthController {
|
|
|
@PostMapping(value = "/auth/accountlogin")
|
|
@PostMapping(value = "/auth/accountlogin")
|
|
|
public ApiResult<LoginRespDataVO> login(@RequestBody @Valid SysUserLoginDTO dto) {
|
|
public ApiResult<LoginRespDataVO> login(@RequestBody @Valid SysUserLoginDTO dto) {
|
|
|
//限流时redis中的key
|
|
//限流时redis中的key
|
|
|
- String key = RedisConstant.ACCOUNT_REDIS_KEY_PREFIX + "account:" + dto.getUsername() + ":AccountLogin";
|
|
|
|
|
|
|
+ String key = RedisConstant.ACCOUNT_LOGIN_REDIS_KEY_PREFIX + "account:" + dto.getUsername() + ":AccountLogin";
|
|
|
LoginRespDataVO resultData = this.getResultData(null, key);
|
|
LoginRespDataVO resultData = this.getResultData(null, key);
|
|
|
resultData.setCommitTopCount(LimitConstant.login_max);
|
|
resultData.setCommitTopCount(LimitConstant.login_max);
|
|
|
//计算封禁结束时间
|
|
//计算封禁结束时间
|
|
@@ -141,11 +141,13 @@ public class AdminAuthController {
|
|
|
@SysLog(value = "第二步后台用户登录发送登录短信验证码", extension = SysLogAspectExtensionForSmsCodeLogin.class, queryIPLocation = true)
|
|
@SysLog(value = "第二步后台用户登录发送登录短信验证码", extension = SysLogAspectExtensionForSmsCodeLogin.class, queryIPLocation = true)
|
|
|
@Operation(summary = "第二步发送登录短信验证码")
|
|
@Operation(summary = "第二步发送登录短信验证码")
|
|
|
@GetMapping(value = "/auth/sms/smsCode")
|
|
@GetMapping(value = "/auth/sms/smsCode")
|
|
|
- @UseRateLimit(duration = 300, max = 3, strategy = SmsCodeRateLimitStrategy.class)
|
|
|
|
|
|
|
+ @UseRateLimit(duration = 300, max = 3, strategy = SmsCodeRateLimitStrategy.class,mark = "smsCode")
|
|
|
public ApiResult<String> smsCode(@RequestParam String username,
|
|
public ApiResult<String> smsCode(@RequestParam String username,
|
|
|
@Pattern(message = "手机号格式有误", regexp = HelioConstant.Regex.CHINA_MAINLAND_PHONE_NO)
|
|
@Pattern(message = "手机号格式有误", regexp = HelioConstant.Regex.CHINA_MAINLAND_PHONE_NO)
|
|
|
@RequestParam(name = "mobile") String mobile) {
|
|
@RequestParam(name = "mobile") String mobile) {
|
|
|
|
|
|
|
|
|
|
+ //限流时redis中的key,这是没啥用
|
|
|
|
|
+ String key = RedisConstant.SMS_CODE_REDIS_KEY_PREFIX + "smsCode:" + mobile + ":smsCode";
|
|
|
//计算封禁结束时间
|
|
//计算封禁结束时间
|
|
|
DateTime dateTime = DateUtil.offsetSecond(DateUtil.date(), LimitConstant.smsCode_duration);
|
|
DateTime dateTime = DateUtil.offsetSecond(DateUtil.date(), LimitConstant.smsCode_duration);
|
|
|
String formatDateTime = DateUtil.formatDateTime(dateTime);
|
|
String formatDateTime = DateUtil.formatDateTime(dateTime);
|
|
@@ -155,8 +157,13 @@ public class AdminAuthController {
|
|
|
formatDateTime,
|
|
formatDateTime,
|
|
|
LimitConstant.smsCode_duration,
|
|
LimitConstant.smsCode_duration,
|
|
|
TimeUnit.SECONDS);
|
|
TimeUnit.SECONDS);
|
|
|
|
|
+
|
|
|
//账号密码redis中存储的用户信息
|
|
//账号密码redis中存储的用户信息
|
|
|
SysUserLoginBO userInfo = this.getLoginUserInfo(mobile);
|
|
SysUserLoginBO userInfo = this.getLoginUserInfo(mobile);
|
|
|
|
|
+ if (!userInfo.getPhoneNo().equals(mobile)) {
|
|
|
|
|
+ throw new BusinessException(406, "手机号错误");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
String smsCode = SmsUtils.getRandomInt(RedisConstant.SMS_CODE_LENGTH);
|
|
String smsCode = SmsUtils.getRandomInt(RedisConstant.SMS_CODE_LENGTH);
|
|
|
log.info("smsCode--------->{}", smsCode);
|
|
log.info("smsCode--------->{}", smsCode);
|
|
|
LinkedHashMap<String, String> messages = Maps.newLinkedHashMap();
|
|
LinkedHashMap<String, String> messages = Maps.newLinkedHashMap();
|
|
@@ -177,22 +184,31 @@ public class AdminAuthController {
|
|
|
@Pattern(message = "手机号格式有误", regexp = HelioConstant.Regex.CHINA_MAINLAND_PHONE_NO) @RequestParam String mobile,
|
|
@Pattern(message = "手机号格式有误", regexp = HelioConstant.Regex.CHINA_MAINLAND_PHONE_NO) @RequestParam String mobile,
|
|
|
@Pattern(message = "验证码格式有误", regexp = CommitConstant.SMS_CODE) @RequestParam String smsCode) {
|
|
@Pattern(message = "验证码格式有误", regexp = CommitConstant.SMS_CODE) @RequestParam String smsCode) {
|
|
|
|
|
|
|
|
- //账号密码redis中存储的用户信息
|
|
|
|
|
- SysUserLoginBO userInfo = this.getLoginUserInfo(mobile);
|
|
|
|
|
|
|
|
|
|
//限流时redis中的key
|
|
//限流时redis中的key
|
|
|
- String key = RedisConstant.SMS_CODE_REDIS_KEY_PREFIX + "smsCodeLogin:" + mobile + ":smsCodeLogin";
|
|
|
|
|
|
|
+ String key = RedisConstant.SMS_CODE_LOGIN_REDIS_KEY_PREFIX + "smsCodeLogin:" + mobile + ":smsCodeLogin";
|
|
|
LoginRespDataVO resultData = this.getResultData(null, key);
|
|
LoginRespDataVO resultData = this.getResultData(null, key);
|
|
|
resultData.setCommitTopCount(LimitConstant.smsCode_login_max);
|
|
resultData.setCommitTopCount(LimitConstant.smsCode_login_max);
|
|
|
- //计算封禁结束时间
|
|
|
|
|
|
|
+ //计算封禁限流结束时间,存入redis中,在限流拦截器中,获取到这个时间,是为了结束时间保持不变,动态修改 duration 的时间,
|
|
|
|
|
+ // 修改时间在 CustomRedisBasedRateLimitStrategy 的 performRateLimitCheck 方法中,然后由每一个限流拦截器,拦截之后
|
|
|
|
|
+ // 获取这个的结束时间之后,重新计算 duration 时间,重新设定 redis 中的时间
|
|
|
DateTime dateTime = DateUtil.offsetSecond(DateUtil.date(), LimitConstant.smsCode_login_duration);
|
|
DateTime dateTime = DateUtil.offsetSecond(DateUtil.date(), LimitConstant.smsCode_login_duration);
|
|
|
resultData.setEndDateTime(DateUtil.formatDateTime(dateTime));
|
|
resultData.setEndDateTime(DateUtil.formatDateTime(dateTime));
|
|
|
|
|
+
|
|
|
|
|
+ //账号密码redis中存储的用户信息
|
|
|
|
|
+ SysUserLoginBO userInfo = this.getLoginUserInfo(mobile);
|
|
|
//封禁结束时间存入redis中
|
|
//封禁结束时间存入redis中
|
|
|
stringSetRedisTemplate.opsForValue()
|
|
stringSetRedisTemplate.opsForValue()
|
|
|
.set(RedisConstant.SMS_CODE_LOGIN_FAILED_END_DATETIME_PREFIX + mobile,
|
|
.set(RedisConstant.SMS_CODE_LOGIN_FAILED_END_DATETIME_PREFIX + mobile,
|
|
|
resultData.getEndDateTime(),
|
|
resultData.getEndDateTime(),
|
|
|
LimitConstant.smsCode_login_duration,
|
|
LimitConstant.smsCode_login_duration,
|
|
|
TimeUnit.SECONDS);
|
|
TimeUnit.SECONDS);
|
|
|
|
|
+
|
|
|
|
|
+ if (!userInfo.getPhoneNo().equals(mobile)) {
|
|
|
|
|
+ throw new BusinessException(406, "手机号错误");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
Object cacheData = service.get(RedisConstant.SMS_CODE_PREFIX + userInfo.getPhoneNo());
|
|
Object cacheData = service.get(RedisConstant.SMS_CODE_PREFIX + userInfo.getPhoneNo());
|
|
|
if (cacheData == null) {
|
|
if (cacheData == null) {
|
|
|
resultData.setStatus(false);
|
|
resultData.setStatus(false);
|
|
@@ -203,7 +219,6 @@ public class AdminAuthController {
|
|
|
resultData.setStatus(false);
|
|
resultData.setStatus(false);
|
|
|
return ApiResult.data("验证码错误", resultData).setCode(406);
|
|
return ApiResult.data("验证码错误", resultData).setCode(406);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
// 构造用户上下文
|
|
// 构造用户上下文
|
|
|
UserContext userContext = UserContext.builder()
|
|
UserContext userContext = UserContext.builder()
|
|
|
.userId(userInfo.getId())
|
|
.userId(userInfo.getId())
|
|
@@ -229,6 +244,7 @@ public class AdminAuthController {
|
|
|
.permissions(userInfo.getPermissions())
|
|
.permissions(userInfo.getPermissions())
|
|
|
.build();
|
|
.build();
|
|
|
resultData.setTokenInfo(tokenInfo);
|
|
resultData.setTokenInfo(tokenInfo);
|
|
|
|
|
+
|
|
|
return ApiResult.data("登录成功", resultData);
|
|
return ApiResult.data("登录成功", resultData);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -242,17 +258,13 @@ public class AdminAuthController {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
- public SysUserLoginBO getLoginUserInfo(String mobile) {
|
|
|
|
|
|
|
+ public SysUserLoginBO getLoginUserInfo(String mobile) throws BusinessException {
|
|
|
//获取redis中的用户信息
|
|
//获取redis中的用户信息
|
|
|
Object object = stringSetRedisTemplate.opsForValue().get(RedisConstant.LOGIN_USER_INFO_PREFIX + mobile);
|
|
Object object = stringSetRedisTemplate.opsForValue().get(RedisConstant.LOGIN_USER_INFO_PREFIX + mobile);
|
|
|
if (object == null) {
|
|
if (object == null) {
|
|
|
throw new BusinessException(407, "登录已超时,需重新登陆");
|
|
throw new BusinessException(407, "登录已超时,需重新登陆");
|
|
|
}
|
|
}
|
|
|
- SysUserLoginBO userInfo = (SysUserLoginBO) object;
|
|
|
|
|
- if (!userInfo.getPhoneNo().equals(mobile)) {
|
|
|
|
|
- throw new BusinessException(406, "手机号错误");
|
|
|
|
|
- }
|
|
|
|
|
- return userInfo;
|
|
|
|
|
|
|
+ return (SysUserLoginBO) object;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public LoginRespDataVO getResultData(String mobile, String key) {
|
|
public LoginRespDataVO getResultData(String mobile, String key) {
|