SockJS传递Auth Header遇401未授权错误求助
核心问题分析
- Stomp.connect参数格式错误:你当前在
connect方法里传递的是嵌套结构{headers: {...}},但Stomp的connect方法第一个参数直接接受headers键值对对象,不需要额外嵌套。 - SockJS的Headers支持限制:SockJS使用原生WebSocket协议时能传递自定义header,但如果连接降级为HTTP轮询/流等fallback方式,浏览器会限制自定义header的传递,导致Authorization头丢失。
修正后的代码
const ws = new SockJS(WebSocketBaseUrl, { headers: { "Authorization": `Bearer ${this.token}` } }); this.stompClientSubscribeUser = Stomp.Stomp.over(ws); const _this = this; // 修正:直接传递headers对象,取消嵌套结构 _this.stompClientSubscribeUser.connect( { "Authorization": `Bearer ${_this.token}` }, function () { _this.stompClientSubscribeUser.subscribe( `/user/${_this.userId}/queue/messages`, function (sdkEvent: any) { _this.onMessageReceived(sdkEvent); } ); }, // 可选:添加错误回调,便于排查连接失败详情 function(error) { console.error('Stomp连接失败:', error); } );
额外优化建议
处理SockJS Fallback的Header传递问题:
若后端基于Spring Boot开发,需在WebSocket配置中允许Authorization头通过SockJS的fallback请求,可通过自定义握手拦截器提取token:@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/queue", "/topic"); config.setUserDestinationPrefix("/user"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws") .setAllowedOriginPatterns("*") .withSockJS() .setInterceptors(new HandshakeInterceptor() { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { // 从请求头提取token,存入attributes供后续认证使用 String authHeader = request.getHeaders().getFirst("Authorization"); if (authHeader != null && authHeader.startsWith("Bearer ")) { attributes.put("token", authHeader.substring(7)); } return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {} }); } }备选方案:URL携带Token:
如果浏览器fallback机制导致header无法传递,可考虑将token放在URL参数中(注意:仅在HTTPS环境下使用,避免明文暴露风险):const ws = new SockJS(`${WebSocketBaseUrl}?token=${this.token}`);后端从请求参数中提取token完成认证逻辑。
内容的提问来源于stack exchange,提问作者Asadbek
相关产品推荐
相关产品推荐

