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