mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
新增个人中心修改密码、管理端重置密码后用户token失效能力
This commit is contained in:
+6
@@ -91,4 +91,10 @@ public interface OAuth2TokenService {
|
||||
*/
|
||||
PageResult<OAuth2AccessTokenDO> getAccessTokenPage(OAuth2AccessTokenPageReqVO reqVO);
|
||||
|
||||
|
||||
/**
|
||||
* 清除userId对应用户的token
|
||||
* @param userId
|
||||
*/
|
||||
void kickOut(Long userId);
|
||||
}
|
||||
|
||||
+22
-16
@@ -29,7 +29,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -240,9 +239,7 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
|
||||
// 记录到 Redis 中
|
||||
oauth2AccessTokenRedisDAO.set(accessTokenDO);
|
||||
// 异步踢出其他token
|
||||
CompletableFuture.runAsync(() -> {
|
||||
kickOut(userId, currentToken);
|
||||
}).exceptionally(e -> {
|
||||
CompletableFuture.runAsync(() -> kickOut(userId, currentToken)).exceptionally(e -> {
|
||||
log.error("[OAuth2TokenServiceImpl] redis 清空token失败, 用户id:{}, 异常:{}", userId, e);
|
||||
return null;
|
||||
});
|
||||
@@ -256,22 +253,17 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
|
||||
* @param currentToken
|
||||
*/
|
||||
public void kickOut(Long userId, String currentToken) {
|
||||
List<String> matchKeys = new ArrayList<>();
|
||||
Cursor<String> cursor = oauth2AccessTokenRedisDAO.scan();
|
||||
while (cursor.hasNext()) {
|
||||
matchKeys.add(cursor.next());
|
||||
}
|
||||
cursor.close();
|
||||
if (CollUtil.isNotEmpty(matchKeys)) {
|
||||
for (String key : matchKeys) {
|
||||
// 获取key下的用户信息
|
||||
OAuth2AccessTokenDO oAuth2AccessTokenDO = oauth2AccessTokenRedisDAO.getWithKey(key);
|
||||
if (ObjectUtil.equal(userId, oAuth2AccessTokenDO.getUserId()) && !StringUtils.equals(currentToken, oAuth2AccessTokenDO.getAccessToken()) && Boolean.FALSE.equals(oAuth2AccessTokenDO.getIsSupAdmin())) {
|
||||
// 用户id匹配、非当次登录token、非超管 -> 删除redis中的token缓存
|
||||
oauth2AccessTokenRedisDAO.deleteWithKey(key);
|
||||
}
|
||||
String key = cursor.next();
|
||||
// 获取key下的用户信息
|
||||
OAuth2AccessTokenDO oAuth2AccessTokenDO = oauth2AccessTokenRedisDAO.getWithKey(key);
|
||||
if (ObjectUtil.equal(userId, oAuth2AccessTokenDO.getUserId()) && !StringUtils.equals(currentToken, oAuth2AccessTokenDO.getAccessToken()) && Boolean.FALSE.equals(oAuth2AccessTokenDO.getIsSupAdmin())) {
|
||||
// 用户id匹配、非当次登录token、非超管 -> 删除redis中的token缓存
|
||||
oauth2AccessTokenRedisDAO.deleteWithKey(key);
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -284,4 +276,18 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
|
||||
return IdUtil.fastSimpleUUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kickOut(Long userId) {
|
||||
Cursor<String> cursor = oauth2AccessTokenRedisDAO.scan();
|
||||
while (cursor.hasNext()) {
|
||||
String key = cursor.next();
|
||||
// 获取key下的用户信息
|
||||
OAuth2AccessTokenDO oAuth2AccessTokenDO = oauth2AccessTokenRedisDAO.getWithKey(key);
|
||||
if (ObjectUtil.equal(userId, oAuth2AccessTokenDO.getUserId())) {
|
||||
// 用户id匹配 -> 删除redis中的token缓存
|
||||
oauth2AccessTokenRedisDAO.deleteWithKey(key);
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
+24
@@ -47,6 +47,7 @@ import com.cf.imes.module.system.enums.logger.LoginResultEnum;
|
||||
import com.cf.imes.module.system.enums.sms.SmsSceneEnum;
|
||||
import com.cf.imes.module.system.service.dept.DeptService;
|
||||
import com.cf.imes.module.system.service.logger.LoginLogService;
|
||||
import com.cf.imes.module.system.service.oauth2.OAuth2TokenService;
|
||||
import com.cf.imes.module.system.service.organ.OrganService;
|
||||
import com.cf.imes.module.system.service.permission.PermissionService;
|
||||
import com.cf.imes.module.system.service.sms.SmsCodeService;
|
||||
@@ -68,6 +69,7 @@ import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -119,6 +121,9 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
@Resource
|
||||
private I18nUtils i18nUtils;
|
||||
|
||||
@Resource
|
||||
private OAuth2TokenService oAuth2TokenService;
|
||||
|
||||
// 定义密码校验的正则表达式
|
||||
private static final String LENGTH_PATTERN = ".{8,}";
|
||||
private static final String UPPER_LETTER_PATTERN = ".*[A-Z].*";
|
||||
@@ -261,6 +266,22 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
AdminUserDO updateObj = new AdminUserDO().setId(id);
|
||||
updateObj.setPassword(encodePassword(reqVO.getNewPassword())); // 加密密码
|
||||
userMapper.updateById(updateObj);
|
||||
|
||||
// 踢出登录
|
||||
asyncKickOut(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步踢出登录
|
||||
*
|
||||
* @param userId
|
||||
*/
|
||||
private void asyncKickOut(Long userId) {
|
||||
// 踢出登录
|
||||
CompletableFuture.runAsync(() -> oAuth2TokenService.kickOut(userId)).exceptionally(e -> {
|
||||
log.error("[AdminUserServiceImpl] redis 清空token失败, 用户id:{}, 异常:{}", userId, e);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -287,6 +308,9 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
validatePassword(password);
|
||||
updateObj.setPassword(encodePassword(password)); // 加密密码
|
||||
userMapper.updateById(updateObj);
|
||||
|
||||
// 踢出登录
|
||||
asyncKickOut(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user