問題描述:一個用戶登錄時,會把他的session當token存進redis。
然後另一個用戶登錄時,取的sessionId是同一個token。查了半天,還沒查出是什麼原因 。
調試時發現session對象不是同一個,但是sessionId取出來卻是一樣的。個人認爲是session.getId時取是的redis裏面的sessionId
正在排查。代碼如下
public class RedisSessionDao extends AbstractSessionDAO {
private final String PREFIX="shiro_redis_session:";
private static Logger logger = LoggerFactory.getLogger(RedisSessionDao.class);
private RedisTemplate redisTpl;
@Value("${session.timeout}")
private Long sessionTimeout;
@Override
public void update(Session session) {
if (session==null || session.getId() == null){
logger.error("redis update session error:session or session id is null");
return;
}
try {
// redisTpl.opsForValue().set(PREFIX+session.getId().toString(), session, sessionTimeout, TimeUnit.HOURS);
redisTpl.opsForValue().set(PREFIX+session.getId().toString(), session, sessionTimeout, TimeUnit.MINUTES);
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new UnknownSessionException(e);
}
}
@Override
public void delete(Session session) {
if (session==null || session.getId() == null){
logger.error("redis delete session error:session or session id is null");
return;
}
try {
redisTpl.delete(PREFIX+session.getId().toString());
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
@Override
public Collection<Session> getActiveSessions() {
return (Collection<Session>) redisTpl.execute(new RedisCallback<Collection<Session>>() {
@Override
public Collection<Session> doInRedis(RedisConnection connection) throws DataAccessException {
Set<Session> sessions = new HashSet<Session>();
Set keys = redisTpl.keys(PREFIX+"*");
for(Object key : keys){
Session session=(Session) redisTpl.opsForValue().get(key);
sessions.add(session);
}
//
// for (Session session : sessions) {
// sessions.add(session);
// }
return sessions;
}
});
}
@Override
protected Serializable doCreate(Session session) {
if (session==null){
logger.error("redis create session error:session is null");
return null;
}
Serializable sessionId = generateSessionId(session);
assignSessionId(session, sessionId);
redisTpl.opsForValue().set(PREFIX+sessionId.toString(), session, session.getTimeout()/1000, TimeUnit.SECONDS);
return sessionId;
}
@Override
protected Session doReadSession(Serializable sessionId) {
if (sessionId == null){
logger.error("redis read session error:sessionId is null");
return null;
}
Session session = null;
try {
session = (Session) redisTpl.opsForValue().get(PREFIX+sessionId.toString());
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return session;
}
public void setRedisTpl(RedisTemplate redisTpl) {
this.redisTpl = redisTpl;
}
}
上面代碼,在redis執行update的時候,取的sessionId是上一個,所以後面用戶返的sessionId就是上一個的,困擾好久,暫未解決。