spring-boot redis:如何使用户的所有会话无效?

我是Redis的新手。我已经按照本教程将HttpSession与redis一起使用。

https://docs.spring.io/spring-

session/docs/current/reference/html5/guides/boot.html

现在,我的应用程序具有“从所有设备注销”选项。单击后,如何删除或使该用户的所有会话无效?

另外,当用户更改密码时,如何使除当前会话之外的所有会话无效?

我尝试使用会话注册表。

@Autowired

private FindByIndexNameSessionRepository sessionRepository;

@Autowired

FindByIndexNameSessionRepository<? extends ExpiringSession> sessions;

@RequestMapping(value = "/logoutalldevices", method = RequestMethod.GET)

public Response test(HttpServletRequest request, HttpServletResponse response) throws Exception {

SpringSessionBackedSessionRegistry sessionRegistry = new SpringSessionBackedSessionRegistry(sessionRepository);

Collection<? extends ExpiringSession> usersSessions = sessions

.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, "myUserId")

.values();

usersSessions.forEach((temp) -> {

String sessionId = temp.getId();

// sessionRegistry.removeSessionInformation(sessionId);

SessionInformation info = sessionRegistry.getSessionInformation(sessionId);

info.expireNow();

});

return Response.ok().build();

}

但这不是从redis

db中删除会话或使会话无效。尽管它向名为’sessionAttr:org.springframework.session.security.SpringSessionBackedSessionInformation.EXPIRED’的会话添加了一个值为true的新属性。我可以使用redis

client在redis db中看到这个新的键值对

HGETALL 'sessionid'

我尝试使用redistemplate从redis db手动删除会话。

@Autowired

RedisTemplate<String, String> redisTemplate;

---------

redisTemplate.delete("spring:session:sessions:" + sessionId);

redisTemplate.delete("spring:session:sessions:expires:" + sessionId);

这几乎可行。它从redis db中删除值,但不删除密钥。

127.0.0.1:6379> keys *

1) "spring:session:sessions:25635a14-a4f1-4aa1-bf5a-bc20f972eec7"

2) "spring:session:sessions:expires:25635a14-a4f1-4aa1-bf5a-bc20f972eec7"

3) "spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:1"

127.0.0.1:6379> hgetall spring:session:sessions:25635a14-a4f1-4aa1-bf5a-bc20f972eec7

1) "lastAccessedTime"

2) "\xac\xed\x00\x05sr\x00\x0ejava.lang.Long;\x8b\xe4\x90\xcc\x8f#\xdf\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x01[R'\x15\xc1"

127.0.0.1:6379>

它删除了会话中除lastAccessedTime时间之外的所有其他键值对。

还有一个奇怪的是,这是我在redisTemplate.delete("key")执行时在redis监视器中看到的日志:

1491731944.899711 [0 127.0.0.1:62816] "DEL" "spring:session:sessions:25635a14-a4f1-4aa1-bf5a-bc20f972eec7"

1491731944.899853 [0 127.0.0.1:62816] "DEL" "spring:session:sessions:expires:25635a14-a4f1-4aa1-bf5a-bc20f972eec7"

如果我将以上两个命令复制并粘贴到redis-client并执行,则密钥将被删除。我再执行一次也看不到键keys

*。我不知道为什么在使用RedisTemplate

127.0.0.1:6379> "DEL" "spring:session:sessions:25635a14-a4f1-4aa1-bf5a-bc20f972eec7"

(integer) 1

127.0.0.1:6379> "DEL" "spring:session:sessions:expires:25635a14-a4f1-4aa1-bf5a-bc20f972eec7"

(integer) 1

127.0.0.1:6379> keys *

1) "spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:1"

127.0.0.1:6379>

回答:

我想知道你是 因为用户会话无效

    usersSessions.forEach((session) -> {        

sessionRegistry.getSessionInformation(session.getId()).expireNow();

});

注意事项

SessionInformation.expireNow()

并不意味着要从redis数据库中删除条目,它只是将您已提到的过期属性附加到会话。

这是ConcurrentSessionFilter发挥作用的地方,

.doFilter()方法实现了automatically logging out

这是 *

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)

throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) req;

HttpServletResponse response = (HttpServletResponse) res;

HttpSession session = request.getSession(false);

if (session != null) {

SessionInformation info = sessionRegistry.getSessionInformation(session

.getId());

if (info != null) {

if (info.isExpired()) {

// Expired - abort processing

doLogout(request, response);

String targetUrl = determineExpiredUrl(request, info);

if (targetUrl != null) {

redirectStrategy.sendRedirect(request, response, targetUrl);

return;

}

else {

response.getWriter().print(

"This session has been expired (possibly due to multiple concurrent "

+ "logins being attempted as the same user).");

response.flushBuffer();

}

return;

}

else {

// Non-expired - update last request date/time

sessionRegistry.refreshLastRequest(info.getSessionId());

}

}

}

chain.doFilter(request, response);

}

为此加油!

以上是 spring-boot redis:如何使用户的所有会话无效? 的全部内容, 来源链接: utcz.com/qa/421339.html

回到顶部