【auth】重构sessionManager

pull/3/head
fengshuonan 2020-12-25 13:52:36 +08:00
parent c6bd3aebdf
commit 2a4f76ce32
9 changed files with 179 additions and 218 deletions

View File

@ -59,12 +59,24 @@
<artifactId>spring-web</artifactId>
</dependency>
<!--redis的依赖-->
<!--缓存的依赖-->
<!--session manager可以用redis可以用内存的-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<optional>true</optional>
<groupId>com.sedinbj.kernel</groupId>
<artifactId>cache-api</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.sedinbj.kernel</groupId>
<artifactId>cache-sdk-memory</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sedinbj.kernel</groupId>
<artifactId>cache-sdk-redis</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@ -1,32 +1,26 @@
package cn.stylefeng.roses.kernel.auth.session;
import cn.hutool.cache.impl.TimedCache;
import cn.stylefeng.roses.kernel.auth.api.SessionManagerApi;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import com.sedinbj.kernel.cache.api.CacheOperatorApi;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static cn.stylefeng.roses.kernel.auth.api.constants.AuthConstants.LOGGED_TOKEN_PREFIX;
import static cn.stylefeng.roses.kernel.auth.api.constants.AuthConstants.LOGGED_USERID_PREFIX;
/**
*
* redis
*
* @author fengshuonan
* @date 2019-09-28-14:43
*/
public class MemoryCacheSessionManager implements SessionManagerApi {
public class DefaultSessionManager implements SessionManagerApi {
/**
*
* <p>
* key LOGGED_TOKEN_PREFIX + token
*/
private final TimedCache<String, LoginUser> loginUserCache;
private final CacheOperatorApi<LoginUser> loginUserCache;
/**
* tokentoken
@ -37,57 +31,60 @@ public class MemoryCacheSessionManager implements SessionManagerApi {
* <p>
* tokenset
*/
private final Map<String, Set<String>> loginTokenCache = new HashMap<>();
private final CacheOperatorApi<Set<String>> allPlaceLoginTokenCache;
public MemoryCacheSessionManager(TimedCache<String, LoginUser> loginUserCache) {
/**
* session
*/
private final Long sessionExpiredSeconds;
public DefaultSessionManager(CacheOperatorApi<LoginUser> loginUserCache, CacheOperatorApi<Set<String>> allPlaceLoginTokenCache, Long sessionExpiredSeconds) {
this.loginUserCache = loginUserCache;
this.allPlaceLoginTokenCache = allPlaceLoginTokenCache;
this.sessionExpiredSeconds = sessionExpiredSeconds;
}
@Override
public void createSession(String token, LoginUser loginUser) {
// 装配用户信息的缓存
loginUserCache.put(getTokenKey(token), loginUser);
loginUserCache.put(token, loginUser, sessionExpiredSeconds);
// 装配用户token的缓存
String userIdKey = getUserIdKey(loginUser.getUserId());
Set<String> theUserTokens = loginTokenCache.get(userIdKey);
Set<String> theUserTokens = allPlaceLoginTokenCache.get(loginUser.getUserId().toString());
if (theUserTokens == null) {
HashSet<String> tempUserTokens = new HashSet<>();
tempUserTokens.add(token);
loginTokenCache.put(userIdKey, tempUserTokens);
} else {
theUserTokens.add(token);
theUserTokens = new HashSet<>();
}
theUserTokens.add(token);
allPlaceLoginTokenCache.put(loginUser.getUserId().toString(), theUserTokens);
}
@Override
public LoginUser getSession(String token) {
return loginUserCache.get(getTokenKey(token));
return loginUserCache.get(token);
}
@Override
public void removeSession(String token) {
String tokenKey = getTokenKey(token);
LoginUser loginUser = loginUserCache.get(tokenKey);
LoginUser loginUser = loginUserCache.get(token);
// 删除用户id对应token的缓存
// 删除本token用户信息的缓存
loginUserCache.remove(token);
// 删除多端登录信息
if (loginUser != null) {
Long userId = loginUser.getUserId();
Set<String> userTokens = loginTokenCache.get(getUserIdKey(userId));
Set<String> userTokens = allPlaceLoginTokenCache.get(userId.toString());
if (userTokens != null) {
userTokens.remove(token);
// 如果删除后size为0则把整个key删掉
if (userTokens.size() == 0) {
loginTokenCache.remove(getUserIdKey(userId));
allPlaceLoginTokenCache.remove(userId.toString());
}
}
}
// 删除用户信息的缓存
loginUserCache.remove(getTokenKey(token));
}
@Override
@ -107,40 +104,20 @@ public class MemoryCacheSessionManager implements SessionManagerApi {
// 设置用户id对应的token列表为参数token
HashSet<String> tokenSet = new HashSet<>();
tokenSet.add(token);
loginTokenCache.put(getUserIdKey(userId), tokenSet);
allPlaceLoginTokenCache.put(userId.toString(), tokenSet);
}
@Override
public boolean haveSession(String token) {
return loginUserCache.containsKey(getTokenKey(token));
return loginUserCache.contains(token);
}
@Override
public void refreshSession(String token) {
LoginUser loginUser = loginUserCache.get(getTokenKey(token));
LoginUser loginUser = loginUserCache.get(token);
if (loginUser != null) {
loginUserCache.put(LOGGED_TOKEN_PREFIX + token, loginUser, loginUserCache.timeout());
loginUserCache.expire(token, sessionExpiredSeconds);
}
}
/**
* tokenkey
*
* @author fengshuonan
* @date 2020/10/21 15:09
*/
private String getTokenKey(String token) {
return LOGGED_TOKEN_PREFIX + token;
}
/**
* idkey
*
* @author fengshuonan
* @date 2020/10/21 15:10
*/
private String getUserIdKey(Long userId) {
return LOGGED_USERID_PREFIX + userId;
}
}

View File

@ -1,159 +0,0 @@
package cn.stylefeng.roses.kernel.auth.session;
import cn.stylefeng.roses.kernel.auth.api.SessionManagerApi;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import com.alibaba.fastjson.parser.ParserConfig;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static cn.stylefeng.roses.kernel.auth.api.constants.AuthConstants.LOGGED_TOKEN_PREFIX;
import static cn.stylefeng.roses.kernel.auth.api.constants.AuthConstants.LOGGED_USERID_PREFIX;
/**
* redis
*
* @author fengshuonan
* @date 2019-09-28-14:43
*/
public class RedisSessionManager implements SessionManagerApi {
/**
*
* <p>
* key LOGGED_TOKEN_PREFIX + token
*/
private final RedisTemplate<String, LoginUser> loginUserRedisTemplate;
/**
* tokentoken
* <p>
* token访
* <p>
* key LOGGED_USERID_PREFIX + id
* <p>
* tokenset
*/
private final RedisTemplate<String, Set<String>> loginTokenRedisTemplate;
/**
* session
*/
private final Long sessionExpiredSeconds;
public RedisSessionManager(RedisTemplate<String, LoginUser> loginUserRedisTemplate, RedisTemplate<String, Set<String>> loginTokenRedisTemplate, Long sessionExpiredSeconds) {
this.loginUserRedisTemplate = loginUserRedisTemplate;
this.loginTokenRedisTemplate = loginTokenRedisTemplate;
this.sessionExpiredSeconds = sessionExpiredSeconds;
}
@Override
public void createSession(String token, LoginUser loginUser) {
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
// 装配用户信息的缓存
loginUserRedisTemplate.opsForValue().set(getTokenKey(token), loginUser, sessionExpiredSeconds, TimeUnit.SECONDS);
// 装配用户token的缓存
String userIdKey = getUserIdKey(loginUser.getUserId());
Set<String> theUserTokens = loginTokenRedisTemplate.opsForValue().get(userIdKey);
if (theUserTokens == null) {
HashSet<String> tempUserTokens = new HashSet<>();
tempUserTokens.add(token);
loginTokenRedisTemplate.opsForValue().set(userIdKey, tempUserTokens);
} else {
theUserTokens.add(token);
}
}
@Override
public LoginUser getSession(String token) {
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
return loginUserRedisTemplate.opsForValue().get(getTokenKey(token));
}
@Override
public void removeSession(String token) {
String tokenKey = getTokenKey(token);
LoginUser loginUser = loginUserRedisTemplate.opsForValue().get(tokenKey);
// 删除用户id对应token的缓存
if (loginUser != null) {
Long userId = loginUser.getUserId();
Set<String> userTokens = loginTokenRedisTemplate.opsForValue().get(getUserIdKey(userId));
if (userTokens != null) {
userTokens.remove(token);
// 如果删除后size为0则把整个key删掉
if (userTokens.size() == 0) {
loginUserRedisTemplate.delete(getUserIdKey(userId));
}
}
}
// 删除用户信息的缓存
loginUserRedisTemplate.delete(getTokenKey(token));
}
@Override
public void removeSessionExcludeToken(String token) {
// 获取token对应的会话
LoginUser session = this.getSession(token);
// 如果会话为空,直接返回
if (session == null) {
return;
}
// 获取用户id
Long userId = session.getUserId();
// 设置用户id对应的token列表为参数token
HashSet<String> tokenSet = new HashSet<>();
tokenSet.add(token);
loginTokenRedisTemplate.opsForValue().set(getUserIdKey(userId), tokenSet);
}
@Override
public boolean haveSession(String token) {
Boolean flag = loginUserRedisTemplate.hasKey(getTokenKey(token));
if (flag == null) {
return false;
} else {
return flag;
}
}
@Override
public void refreshSession(String token) {
LoginUser loginUser = loginUserRedisTemplate.boundValueOps(getTokenKey(token)).get();
if (loginUser != null) {
loginUserRedisTemplate.boundValueOps(getTokenKey(token)).expire(sessionExpiredSeconds, TimeUnit.SECONDS);
}
}
/**
* tokenkey
*
* @author fengshuonan
* @date 2020/10/21 15:09
*/
private String getTokenKey(String token) {
return LOGGED_TOKEN_PREFIX + token;
}
/**
* idkey
*
* @author fengshuonan
* @date 2020/10/21 15:10
*/
private String getUserIdKey(Long userId) {
return LOGGED_USERID_PREFIX + userId;
}
}

View File

@ -0,0 +1,28 @@
package cn.stylefeng.roses.kernel.auth.session.cache.logintoken;
import cn.hutool.cache.impl.TimedCache;
import com.sedinbj.kernel.cache.AbstractMemoryCacheOperator;
import java.util.Set;
import static cn.stylefeng.roses.kernel.auth.api.constants.AuthConstants.LOGGED_USERID_PREFIX;
/**
* token
*
* @author fengshuonan
* @date 2020/12/24 19:16
*/
public class MemoryLoginTokenCache extends AbstractMemoryCacheOperator<Set<String>> {
public MemoryLoginTokenCache(TimedCache<String, Set<String>> timedCache) {
super(timedCache);
}
@Override
public String getCommonKeyPrefix() {
return LOGGED_USERID_PREFIX;
}
}

View File

@ -0,0 +1,28 @@
package cn.stylefeng.roses.kernel.auth.session.cache.logintoken;
import com.sedinbj.kernel.cache.AbstractRedisCacheOperator;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.Set;
import static cn.stylefeng.roses.kernel.auth.api.constants.AuthConstants.LOGGED_USERID_PREFIX;
/**
* redistoken
*
* @author fengshuonan
* @date 2020/12/24 19:16
*/
public class RedisLoginTokenCache extends AbstractRedisCacheOperator<Set<String>> {
public RedisLoginTokenCache(RedisTemplate<String, Set<String>> redisTemplate) {
super(redisTemplate);
}
@Override
public String getCommonKeyPrefix() {
return LOGGED_USERID_PREFIX;
}
}

View File

@ -0,0 +1,26 @@
package cn.stylefeng.roses.kernel.auth.session.cache.loginuser;
import cn.hutool.cache.impl.TimedCache;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import com.sedinbj.kernel.cache.AbstractMemoryCacheOperator;
import static cn.stylefeng.roses.kernel.auth.api.constants.AuthConstants.LOGGED_TOKEN_PREFIX;
/**
*
*
* @author fengshuonan
* @date 2020/12/24 19:16
*/
public class MemoryLoginUserCache extends AbstractMemoryCacheOperator<LoginUser> {
public MemoryLoginUserCache(TimedCache<String, LoginUser> timedCache) {
super(timedCache);
}
@Override
public String getCommonKeyPrefix() {
return LOGGED_TOKEN_PREFIX;
}
}

View File

@ -0,0 +1,27 @@
package cn.stylefeng.roses.kernel.auth.session.cache.loginuser;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import com.sedinbj.kernel.cache.AbstractRedisCacheOperator;
import org.springframework.data.redis.core.RedisTemplate;
import static cn.stylefeng.roses.kernel.auth.api.constants.AuthConstants.LOGGED_TOKEN_PREFIX;
/**
* redis
*
* @author fengshuonan
* @date 2020/12/24 19:16
*/
public class RedisLoginUserCache extends AbstractRedisCacheOperator<LoginUser> {
public RedisLoginUserCache(RedisTemplate<String, LoginUser> redisTemplate) {
super(redisTemplate);
}
@Override
public String getCommonKeyPrefix() {
return LOGGED_TOKEN_PREFIX;
}
}

View File

@ -24,6 +24,13 @@
<version>1.0.0</version>
</dependency>
<!--默认使用内存-->
<dependency>
<groupId>com.sedinbj.kernel</groupId>
<artifactId>cache-sdk-memory</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>

View File

@ -1,17 +1,25 @@
package cn.stylefeng.roses.kernel.auth.starter;
import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.stylefeng.roses.kernel.auth.api.SessionManagerApi;
import cn.stylefeng.roses.kernel.auth.api.expander.AuthConfigExpander;
import cn.stylefeng.roses.kernel.auth.api.password.PasswordStoredEncryptApi;
import cn.stylefeng.roses.kernel.auth.api.password.PasswordTransferEncryptApi;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import cn.stylefeng.roses.kernel.auth.password.BcryptPasswordStoredEncrypt;
import cn.stylefeng.roses.kernel.auth.password.RsaPasswordTransferEncrypt;
import cn.stylefeng.roses.kernel.auth.session.MemoryCacheSessionManager;
import cn.stylefeng.roses.kernel.auth.session.DefaultSessionManager;
import cn.stylefeng.roses.kernel.auth.session.cache.logintoken.MemoryLoginTokenCache;
import cn.stylefeng.roses.kernel.auth.session.cache.loginuser.MemoryLoginUserCache;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Set;
import static com.sedinbj.kernel.cache.api.constants.CacheConstants.NONE_EXPIRED_TIME;
/**
*
*
@ -57,7 +65,14 @@ public class GunsAuthAutoConfiguration {
@ConditionalOnMissingBean(SessionManagerApi.class)
public SessionManagerApi sessionManagerApi() {
Long sessionExpiredSeconds = AuthConfigExpander.getSessionExpiredSeconds();
return new MemoryCacheSessionManager(CacheUtil.newTimedCache(sessionExpiredSeconds * 1000));
TimedCache<String, LoginUser> loginUsers = CacheUtil.newTimedCache(1000L * sessionExpiredSeconds);
TimedCache<String, Set<String>> loginTokens = CacheUtil.newTimedCache(NONE_EXPIRED_TIME);
MemoryLoginUserCache memoryLoginUserCache = new MemoryLoginUserCache(loginUsers);
MemoryLoginTokenCache memoryLoginTokenCache = new MemoryLoginTokenCache(loginTokens);
return new DefaultSessionManager(memoryLoginUserCache, memoryLoginTokenCache, sessionExpiredSeconds);
}
}