React+Spring Boot SockJS WebSocket连接立即断开问题求助
排查React + Spring Boot SockJS WebSocket连接立即关闭问题
1. 确认JWT拦截规则是否排除WebSocket端点
- 若后端用了JWT拦截器/过滤器,必须确保WebSocket端点(比如
/ws/**)被排除。SockJS握手是HTTP请求,若拦截器强制要求所有请求带Token,而握手请求未携带会直接被拒绝,导致连接关闭。 - 检查
WebSecurityConfig类,在configure(HttpSecurity http)方法中添加:
http.authorizeRequests() .antMatchers("/ws/**").permitAll() // 排除WebSocket相关路径 .anyRequest().authenticated();
- 自定义过滤器需在逻辑中判断请求路径,跳过WebSocket相关请求的Token校验。
2. 修正SockJS握手请求的Token传递方式
- 浏览器不支持在WebSocket升级请求中自定义Header传递JWT,需将Token放在查询参数里:
React端代码调整:
const socket = new SockJS(`http://localhost:8080/ws?token=${yourJwtToken}`);
- 后端通过
HandshakeInterceptor获取并校验查询参数中的Token:
public class WebSocketHandshakeInterceptor implements HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { String query = request.getURI().getQuery(); if (query != null && query.contains("token=")) { String token = query.split("token=")[1]; // 执行JWT校验逻辑,校验失败返回false拒绝握手 } return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {} }
- 在WebSocket配置类中注册拦截器:
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws") .setAllowedOrigins("http://localhost:3000") // 替换为实际前端域名 .withSockJS() .setInterceptors(new WebSocketHandshakeInterceptor()); } }
3. 检查CORS配置是否兼容WebSocket握手
- SockJS会先发送OPTIONS预检请求,需确保CORS配置允许该请求方法及前端Origin:
@Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Arrays.asList("http://localhost:3000")); config.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS")); config.setAllowCredentials(true); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); }
4. 通过后端日志定位具体错误
- 开启Spring Boot的DEBUG日志,关注
org.springframework.web.socket包的日志,查找Handshake failed、Invalid token、CORS origin not allowed等关键词,直接定位失败原因。
5. Postman测试的正确姿势
- 测试SockJS需模拟握手流程:先发送GET请求到
/ws/info获取初始化信息,再用Postman的WebSocket客户端选择SockJS模式,传入包含Token的完整连接地址。
内容的提问来源于stack exchange,提问作者TheStruggleEzzReal
相关产品推荐
相关产品推荐

