forked from github/dataease
Merge pull request #4784 from dataease/pr@dev@perf_multi_login_cache
perf(登录): 多端登录限制缓存优化
This commit is contained in:
commit
5244c65095
@ -9,11 +9,9 @@ import com.auth0.jwt.interfaces.Verification;
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.auth.entity.TokenInfo;
|
||||
import io.dataease.auth.entity.TokenInfo.TokenInfoBuilder;
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.commons.model.OnlineUserModel;
|
||||
import io.dataease.commons.utils.*;
|
||||
import io.dataease.exception.DataEaseException;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
@ -23,7 +21,6 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class JWTUtils {
|
||||
|
||||
@ -96,13 +93,9 @@ public class JWTUtils {
|
||||
|
||||
}
|
||||
|
||||
private static Set<OnlineUserModel> filterValid(Set<OnlineUserModel> userModels) {
|
||||
Set<OnlineUserModel> models = userModels.stream().filter(JWTUtils::tokenValid).collect(Collectors.toSet());
|
||||
|
||||
return models;
|
||||
}
|
||||
|
||||
private static String models2Json(Set<OnlineUserModel> models, boolean withCurToken, String token) {
|
||||
private static String models2Json(OnlineUserModel model, boolean withCurToken, String token) {
|
||||
Set<OnlineUserModel> models = new LinkedHashSet<>();
|
||||
models.add(model);
|
||||
Gson gson = new Gson();
|
||||
List<OnlineUserModel> userModels = models.stream().map(item -> {
|
||||
item.setToken(null);
|
||||
@ -120,31 +113,25 @@ public class JWTUtils {
|
||||
}
|
||||
|
||||
public static String seizeSign(Long userId, String token) {
|
||||
Set<OnlineUserModel> userModels = Optional.ofNullable(TokenCacheUtils.onlineUserTokens(userId)).orElse(new LinkedHashSet<>());
|
||||
userModels.stream().forEach(model -> {
|
||||
TokenCacheUtils.add(model.getToken(), userId);
|
||||
});
|
||||
userModels.clear();
|
||||
OnlineUserModel curModel = TokenCacheUtils.buildModel(token);
|
||||
userModels.add(curModel);
|
||||
TokenCacheUtils.resetOnlinePools(userId, userModels);
|
||||
Optional.ofNullable(TokenCacheUtils.onlineUserToken(userId)).ifPresent(model -> TokenCacheUtils.add(model.getToken(), userId));
|
||||
TokenCacheUtils.add2OnlinePools(token, userId);
|
||||
return IPUtils.get();
|
||||
}
|
||||
|
||||
public static String sign(TokenInfo tokenInfo, String secret, boolean writeOnline) {
|
||||
|
||||
Long userId = tokenInfo.getUserId();
|
||||
String multiLoginType = null;
|
||||
if (writeOnline && StringUtils.equals("1", (multiLoginType = TokenCacheUtils.multiLoginType()))) {
|
||||
Set<OnlineUserModel> userModels = TokenCacheUtils.onlineUserTokens(userId);
|
||||
if (CollectionUtils.isNotEmpty(userModels) && CollectionUtils.isNotEmpty((userModels = filterValid(userModels)))) {
|
||||
TokenCacheUtils.resetOnlinePools(userId, userModels);
|
||||
OnlineUserModel userModel = TokenCacheUtils.onlineUserToken(userId);
|
||||
if (ObjectUtils.isNotEmpty(userModel) && tokenValid(userModel)) {
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
Cookie cookie_token = new Cookie("MultiLoginError1", models2Json(userModels, false, null));cookie_token.setPath("/");
|
||||
Cookie cookie_token = new Cookie("MultiLoginError1", models2Json(userModel, false, null));
|
||||
cookie_token.setPath("/");
|
||||
cookie_token.setPath("/");
|
||||
response.addCookie(cookie_token);
|
||||
DataEaseException.throwException("MultiLoginError1");
|
||||
}
|
||||
|
||||
}
|
||||
if (ObjectUtils.isEmpty(expireTime)) {
|
||||
expireTime = CommonBeanFactory.getBean(Environment.class).getProperty("dataease.login_timeout", Long.class, 480L);
|
||||
@ -156,23 +143,21 @@ public class JWTUtils {
|
||||
.withClaim("username", tokenInfo.getUsername())
|
||||
.withClaim("userId", userId);
|
||||
String sign = builder.withExpiresAt(date).sign(algorithm);
|
||||
if (writeOnline && !StringUtils.equals("0", multiLoginType)) {
|
||||
|
||||
if (StringUtils.equals("2", multiLoginType)) {
|
||||
Set<OnlineUserModel> userModels = TokenCacheUtils.onlineUserTokens(userId);
|
||||
if (CollectionUtils.isNotEmpty(userModels) && CollectionUtils.isNotEmpty((userModels = filterValid(userModels)))) {
|
||||
OnlineUserModel userModel = TokenCacheUtils.onlineUserToken(userId);
|
||||
if (ObjectUtils.isNotEmpty(userModel) && tokenValid(userModel)) {
|
||||
HttpServletResponse response = ServletUtils.response();
|
||||
Cookie cookie_token = new Cookie("MultiLoginError2", models2Json(userModels, true, sign));
|
||||
Cookie cookie_token = new Cookie("MultiLoginError2", models2Json(userModel, true, sign));
|
||||
cookie_token.setPath("/");
|
||||
response.addCookie(cookie_token);
|
||||
userModels = userModels.stream().filter(mode -> !StringUtils.equals(mode.getToken(), sign)).collect(Collectors.toSet());
|
||||
TokenCacheUtils.resetOnlinePools(userId, userModels);
|
||||
DataEaseException.throwException("MultiLoginError");
|
||||
}
|
||||
}
|
||||
if (writeOnline && !StringUtils.equals("0", multiLoginType)) {
|
||||
TokenCacheUtils.add2OnlinePools(sign, userId);
|
||||
}
|
||||
return sign;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.dataease.commons.utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.commons.model.OnlineUserModel;
|
||||
import io.dataease.listener.util.CacheUtils;
|
||||
import io.dataease.service.system.SystemParameterService;
|
||||
@ -7,12 +8,9 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.SetOperations;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
@ -28,6 +26,8 @@ public class TokenCacheUtils {
|
||||
|
||||
private static Long expTime;
|
||||
|
||||
private static Gson gson = new Gson();
|
||||
|
||||
@Value("${spring.cache.type:ehcache}")
|
||||
public void setCacheType(String cacheType) {
|
||||
TokenCacheUtils.cacheType = cacheType;
|
||||
@ -62,17 +62,6 @@ public class TokenCacheUtils {
|
||||
CacheUtils.flush(KEY);
|
||||
}
|
||||
|
||||
public static void remove(String token) {
|
||||
if (useRedis()) {
|
||||
RedisTemplate redisTemplate = (RedisTemplate) CommonBeanFactory.getBean("redisTemplate");
|
||||
String key = KEY + token;
|
||||
if (redisTemplate.hasKey(key)) {
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
return;
|
||||
}
|
||||
CacheUtils.remove(KEY, token);
|
||||
}
|
||||
|
||||
public static boolean invalid(String token) {
|
||||
if (useRedis()) {
|
||||
@ -83,36 +72,17 @@ public class TokenCacheUtils {
|
||||
return ObjectUtils.isNotEmpty(sys_token_store) && StringUtils.isNotBlank(sys_token_store.toString());
|
||||
}
|
||||
|
||||
public static void resetOnlinePools(Long userId, Set<OnlineUserModel> sets) {
|
||||
public static void add2OnlinePools(String token, Long userId) {
|
||||
OnlineUserModel model = buildModel(token);
|
||||
if (useRedis()) {
|
||||
RedisTemplate redisTemplate = (RedisTemplate) CommonBeanFactory.getBean("redisTemplate");
|
||||
redisTemplate.delete(ONLINE_TOKEN_POOL_KEY + userId);
|
||||
SetOperations setOperations = redisTemplate.opsForSet();
|
||||
Object[] modelArray = sets.stream().toArray();
|
||||
setOperations.add(ONLINE_TOKEN_POOL_KEY + userId, modelArray);
|
||||
ValueOperations valueOperations = cacheHandler();
|
||||
valueOperations.set(ONLINE_TOKEN_POOL_KEY + userId, model, expTime, TimeUnit.MINUTES);
|
||||
return;
|
||||
}
|
||||
CacheUtils.removeAll(ONLINE_TOKEN_POOL_KEY);
|
||||
CacheUtils.put(ONLINE_TOKEN_POOL_KEY, userId, sets, null, null);
|
||||
CacheUtils.flush(ONLINE_TOKEN_POOL_KEY);
|
||||
}
|
||||
|
||||
public static void add2OnlinePools(String token, Long userId) {
|
||||
if (useRedis()) {
|
||||
RedisTemplate redisTemplate = (RedisTemplate) CommonBeanFactory.getBean("redisTemplate");
|
||||
SetOperations setOperations = redisTemplate.opsForSet();
|
||||
setOperations.add(ONLINE_TOKEN_POOL_KEY + userId, buildModel(token));
|
||||
return;
|
||||
}
|
||||
Object listObj = null;
|
||||
Set<OnlineUserModel> models = null;
|
||||
if (ObjectUtils.isEmpty(listObj = CacheUtils.get(ONLINE_TOKEN_POOL_KEY, userId))) {
|
||||
models = new LinkedHashSet<>();
|
||||
} else {
|
||||
models = (Set<OnlineUserModel>) listObj;
|
||||
}
|
||||
models.add(buildModel(token));
|
||||
CacheUtils.put(ONLINE_TOKEN_POOL_KEY, userId, models, null, null);
|
||||
Long time = expTime * 60;
|
||||
Double v = time * 0.6;
|
||||
CacheUtils.put(ONLINE_TOKEN_POOL_KEY, userId, model, time.intValue(), v.intValue());
|
||||
CacheUtils.flush(ONLINE_TOKEN_POOL_KEY);
|
||||
}
|
||||
|
||||
@ -121,16 +91,18 @@ public class TokenCacheUtils {
|
||||
return service.multiLoginType();
|
||||
}
|
||||
|
||||
public static Set<OnlineUserModel> onlineUserTokens(Long userId) {
|
||||
public static OnlineUserModel onlineUserToken(Long userId) {
|
||||
if (useRedis()) {
|
||||
RedisTemplate redisTemplate = (RedisTemplate) CommonBeanFactory.getBean("redisTemplate");
|
||||
SetOperations setOperations = redisTemplate.opsForSet();
|
||||
Set tokens = setOperations.members(ONLINE_TOKEN_POOL_KEY + userId);
|
||||
return tokens;
|
||||
ValueOperations valueOperations = cacheHandler();
|
||||
Object obj = valueOperations.get(ONLINE_TOKEN_POOL_KEY + userId);
|
||||
if (ObjectUtils.isNotEmpty(obj)) return (OnlineUserModel) obj;
|
||||
return null;
|
||||
}
|
||||
Object o = CacheUtils.get(ONLINE_TOKEN_POOL_KEY, userId);
|
||||
if (ObjectUtils.isNotEmpty(o))
|
||||
return (Set<OnlineUserModel>) o;
|
||||
if (ObjectUtils.isNotEmpty(o)) {
|
||||
OnlineUserModel userModel = gson.fromJson(gson.toJson(o), OnlineUserModel.class);
|
||||
return userModel;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user