繁体   English   中英

当您使用REST API和JWT时,如何在春季将stolds websocket会话复制到redis

[英]How do you copy stomp websocket sessions to redis in spring when you are using REST API and JWT

我正在构建一个小的websocket项目,并由JWT令牌机制保护,我想在redis中存储websocket会话而不是本地内存。

@Override
protected void configureStompEndpoints(StompEndpointRegistry registry) {
    registry
            .addEndpoint("/hello")
            .addInterceptors(new HttpSessionHandshakeInterceptor() {
                @Override
                public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                        WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
                    if (request instanceof ServletServerHttpRequest) {
                        ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
                        HttpSession session = servletRequest.getServletRequest().getSession();
                        attributes.put("sessionId", session.getId());
                    }
                    return true;
                }
            })
            .withSockJS()
            .setSessionCookieNeeded(true);
}

我的redis配置中的@EnableRedisHttpSession和上面的源代码安全地将http会话存储在redis中,但即使我刷新了我的redis数据库,我仍然可以向我连接的客户端发送和接收我的消息。

我的猜测是HttpSession与WebSocket会话不同。 如果您使用基于令牌的身份验证,我应该如何“智能地”要求spring以redis方式存储和维护与websocket相关的会话?

更新1

StompHeaderAccessor accessor =
                    MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);

            List<String> tokenList = accessor.getNativeHeader("username");
            accessor.removeHeader("username");

            String username = null;
            if (tokenList != null && tokenList.size() > 0) {
                username = tokenList.get(0);
            }

            AuthenticationToken authToken = new AuthenticationToken(username);
            SecurityContextHolder.getContext().setAuthentication(authToken);

            switch(accessor.getCommand()) {
                case CONNECT:
                    Principal auth = username == null ? null : authToken;
                    accessor.setUser(auth);

                    return MessageBuilder.createMessage(message.getPayload(), accessor.getMessageHeaders());
                case CONNECTED:
                    System.out.println("Stomp connected");
                    break;
                case DISCONNECT:
                    System.out.println("Stomp disconnected");
                    break;
                case SEND:
                    break;
                default:
                    break;
            }
            return message;

更新2

我认为STSP上的Websocket依赖于SimpSessionId而不是握手拦截器中创建的HttpSession。

StompHeaderAccessor [headers={simpMessageType=MESSAGE, stompCommand=SEND, nativeHeaders={username=[*******], destination=[/app/feed], content-length=[81]}, simpSessionAttributes={SPRING.SESSION.ID=187912de-a875-45ef-995a-7723fd8715c8}, simpHeartbeat=[J@6e9173e4, simpUser=***.AuthenticationToken@1767840c: Principal: *******; Credentials: [PROTECTED]; Authenticated: true; Details: null; Not granted any authorities, simpSessionId=d686qam8, simpDestination=/app/feed}]

更新3

SimpUserRegistry称这是“当前连接用户的注册表”。 这可能是答案吗?

更新4

我正在使用RabbitMQ。 这是否意味着我在做什么是完全没用的?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM