【发布时间】:2017-08-22 18:34:31
【问题描述】:
我是 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 客户端在 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执行,key就被删除了。当我不再执行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>
【问题讨论】:
-
你能分享你的spring安全配置吗?
-
我没有设置任何配置。刚刚添加了 spring-boot-starter-security 依赖项。而已。我需要添加一些东西吗?
-
您评论了
// sessionRegistry.removeSessionInformation(sessionId);,应该可以正常工作。你的情况发生了什么? -
我试过了,还是不行。
-
sessionStatus.setComplete()对您的情况有用吗?