Hei*_*erg 14 java session spring redis
我是redis的新手.我已经按照本教程使用了redis的HttpSession.
https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot.html
现在我的应用程序已"退出所有设备"选项.单击该按钮时,如何删除或使该用户的所有会话无效?
此外,当用户更改其密码时,如何使除当前会话之外的所有会话无效?
编辑:
我尝试使用Session Registry.
@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();
}
Run Code Online (Sandbox Code Playgroud)
但它不会从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);
Run Code Online (Sandbox Code Playgroud)
这几乎可行.它从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>
Run Code Online (Sandbox Code Playgroud)
除了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"
Run Code Online (Sandbox Code Playgroud)
如果我将上述两个命令复制并粘贴到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>
Run Code Online (Sandbox Code Playgroud)
我想知道你you are following the correct path为了使用户会话无效
usersSessions.forEach((session) -> {
sessionRegistry.getSessionInformation(session.getId()).expireNow();
});
Run Code Online (Sandbox Code Playgroud)
有些事要注意
SessionInformation.expireNow()
Run Code Online (Sandbox Code Playgroud)
并不意味着从redis数据库中删除条目,它只是将您过期的属性附加到会话中,正如您正确提到的那样.
但是这会如何使用户的会话无效?
这里有ConcurrentSessionFilter,其中
.doFilter()方法可以解决问题automatically logging out
这是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);
}
Run Code Online (Sandbox Code Playgroud)
干杯!
| 归档时间: |
|
| 查看次数: |
8508 次 |
| 最近记录: |