Ich bin neu bei Redis. Ich bin diesem Tutorial gefolgt, um HttpSession mit redis zu verwenden.
https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot.html
Jetzt hat meine Anwendung die Option 'Abmelden von allen Geräten'. Wenn darauf geklickt wird, wie kann ich alle Sitzungen dieses Benutzers entfernen oder ungültig machen?
Wie kann ich auch alle seine Sitzungen außer der aktuellen Sitzung für ungültig erklären, wenn der Benutzer sein Kennwort ändert?
Bearbeiten:
Ich habe versucht, die Sitzungsregistrierung zu verwenden.
@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();
}
Die Sitzung wird jedoch nicht aus redis db entfernt oder ungültig gemacht. Sie fügt der Sitzung jedoch ein neues Attribut mit dem Namen 'sessionAttr: org.springframework.session.security.SpringSessionBackedSessionInformation.EXPIRED' mit dem Wert true hinzu. Ich kann dieses neue Schlüsselwertpaar in redis db mit redis client sehen, wenn ich dies tue
HGETALL 'sessionid'
Bearbeiten
Ich habe versucht, die Sitzung mit redistemplate manuell aus redis db zu löschen.
@Autowired
RedisTemplate<String, String> redisTemplate;
---------
redisTemplate.delete("spring:session:sessions:" + sessionId);
redisTemplate.delete("spring:session:sessions:expires:" + sessionId);
Das funktioniert fast. Der Wert wird aus redis db gelöscht, nicht jedoch der Schlüssel.
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>
Es löschte alle anderen Schlüsselwertpaare innerhalb der Sitzung mit Ausnahme der lastAccessedTime-Zeit.
Eine seltsame Sache ist, das ist das Protokoll, das ich in redis monitor sehe, wenn redisTemplate.delete("key")
ausgeführt wird:
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"
Wenn ich die beiden obigen Befehle kopiere und einfügte, um ihn erneut auszuführen und auszuführen, werden die Schlüssel gelöscht. Ich sehe keine Schlüssel mehr, wenn ich keys *
mehr ausführe. Ich frage mich, warum der Schlüssel nicht gelöscht wird, wenn er mit RedisTemplate
gelöscht wird.
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>
Ich würde Sie gerne wissen, dass you are following the correct path
für das Ungültigmachen der Benutzersitzungen
usersSessions.forEach((session) -> {
sessionRegistry.getSessionInformation(session.getId()).expireNow();
});
Etwas zu beachten
SessionInformation.expireNow()
bedeutet nicht, Einträge aus der redis
-Datenbank zu entfernen, sondern fügt das abgelaufene Attribut einfach an die Sitzung an.
Wie wird die Sitzung des Benutzers jedoch ungültig?
Hier kommt die ConcurrentSessionFilter ins Spiel, wobei die .doFilter()
-Methode den Trick von automatically logging out
ausführt
Hier ist der Ausschnitt für 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);
}
Prost!
Versuchen Sie dies mit dem Löschschlüssel "redisTemplate.opsForValue (). GetOperations (). Delete (KEY);"
Versuche dies
usersSessions.forEach((session) -> {
sessionRegistry.delete(session.getId());
});
Wenn Sie beim Debuggen nur eine einzige Aktion ausführen möchten, müssen Sie sich nur bei redis_cli
Anmelden und alle Redis-Tasten leeren.
$ redis-cli
127.0.0.1:6379> KEYS *
1) "spring:session:index:org.springframework.session.FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME:bbb"
2) "spring:session:expirations:1558782600000"
3) "spring:session:expirations:1558783140000"
4) "spring:session:sessions:expires:953146bf-7300-4394-bbf0-bf606ff6b326"
5) "spring:session:expirations:1558782540000"
6) "spring:session:sessions:953146bf-7300-4394-bbf0-bf606ff6b326"
127.0.0.1:6379> FLUSHALL
OK
127.0.0.1:6379> KEYS *
(empty list or set)
127.0.0.1:6379>