gpt4 book ai didi

java - spring-boot redis : How to invalidate all sessions of a user?

转载 作者:IT老高 更新时间:2023-10-28 13:55:22 27 4
gpt4 key购买 nike

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

https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot.html

现在我的应用程序具有“退出所有设备”选项。单击该按钮后,如何删除或使该用户的所有 session 无效?

此外,当用户更改密码时,我如何使他的所有 session 无效,除了当前 session ?

编辑:

我尝试使用 session 注册表。

@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 中删除 session 或使其无效。尽管它向名为“sessionAttr:org.springframework.session.security.SpringSessionBackedSessionInformation.EXPIRED”的 session 添加了一个新属性,值为true。当我这样做时,我可以使用 redis 客户端在 redis db 中看到这个新的键值对

HGETALL 'sessionid'

编辑

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

@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>

它删除了 session 内的所有其他键值对,除了 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并执行,key就被删除了。当我执行 keys * 时,我看不到键。我想知道为什么使用 RedisTemplate

删除 key 时没有删除 key
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>

最佳答案

我想知道您您正在使用正确的路径来使用户 session 无效

    usersSessions.forEach((session) -> {        
sessionRegistry.getSessionInformation(session.getId()).expireNow();
});

注意事项

SessionInformation.expireNow()

并不是要从 redis 数据库中删除条目,它只是将过期属性附加到 session 中,正如您正确提到的那样。

但这如何使用户的 session 无效?

ConcurrentSessionFilter 来了在哪里玩.doFilter() 方法实现了自动注销

这是 ConcurrentSessionFilter

的片段
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);
}

干杯!

关于java - spring-boot redis : How to invalidate all sessions of a user?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43090679/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com