没有从 headers 得到 SPRING.SESSION.ID

Not getting SPRING.SESSION.ID from headers

我正在使用 spring session 和 AbstractSessionWebSocketMessageBrokerConfigurer 并尝试创建一个支持 Spring 安全和 Spring 的 STOMP Websocket Session。我似乎无法激活我的 session。我使用 webstomp-client 连接 (https://github.com/JSteunou/webstomp-client)

摘要SessionWebSocketMessageBrokerConfigurer 创建

@Bean
@SuppressWarnings("unchecked")
public SessionRepositoryMessageInterceptor<S> sessionRepositoryInterceptor() {
    return new SessionRepositoryMessageInterceptor<S>(this.sessionRepository);
}

我作为 header 传递给连接事件和每条消息

SPRING.SESSION.ID:<My session id>

当我检查 SessionRepositoryMessageInterceptor 中的处理时,我看到它正在尝试通过 SimpMessageHeaderAccessor 检索 session id,期望 header 包含 object header键下的simpSession属性。

Map<String, Object> sessionHeaders = SimpMessageHeaderAccessor
            .getSessionAttributes(message.getHeaders());
    String sessionId = sessionHeaders == null ? null
            : (String) sessionHeaders.get(SPRING_SESSION_ID_ATTR_NAME);

SimpMessageHeaderAccessor 似乎期望的所有属性都没有出现在 stomp 客户端中,只是似乎属于不同的协议。

如何在 Stomp、Spring WebSocket、Spring 安全和 Spring Session 下激活 session?或者更具体地说:

我不知道问题出在哪里,但我可以解释一些事情来帮助您调试问题。

Spring 支持 WebSocket-scoped 属性。只要 session 存在,这些属性就一直存在。 SessionRepositoryMessageInterceptor 作为 HandshakeInterceptor,挂接到初始 HTTP 握手请求并将 SPRING.SESSION.ID 保存为 WebSocket-scoped 属性。然后在握手之后,当 STOMP 消息开始流动时,它会拦截每个传入的消息,并检索 websocket 属性中的 SPRING.SESSION.ID。所以我不确定您为什么要将 SPRING.SESSION.ID 作为 header 传递。正如我刚刚解释并与 WebSocket session.

相关联的那样,这一切都已为您管理好

关于SimpHeaderAccessor vs StompHeaderAcessor的问题,前者是一个更通用的版本。只要它能为您提供足够的信息,使用它就没有错。在这种情况下 Spring Session 不关心 STOMP 的具体细节。

我不明白你的第二个问题,即需要从 javascript 客户端传递什么 header 来创建 session。只要 HTTP 握手是在同一个 HTTP session 中进行的,它就应该可以正常工作。这里与您执行任何 HTTP 调用的方式没有什么不同。