浏览器中STOMP WebSocket连接报401未授权,Postman可正常连接
STOMP WebSocket连接401未授权问题(浏览器失败/Postman成功)
问题描述
通过STOMP协议实现前后端WebSocket通信时出现异常:登录后在浏览器发起连接返回401(Unauthorized),但Postman中相同连接请求返回200(OK)。JWT已存储在浏览器sessionStorage中,尝试构建Authorization请求头传递给stompClient。
客户端代码(原版本)
async function connect() { var socket = new SockJS("http://localhost:8080/api/websocket"); let stompClient = Stomp.over(socket); const token = sessionStorage.getItem("jwtToken"); const headers = { Authorization: "Bearer " + token, }; const headersAuth = { headers }; console.log(headersAuth); stompClient.connect({ headersAuth }, function (frame) { stompClient.subscribe("/topic/events", function (messageOutput) { const msg = JSON.parse(messageOutput.body); if (msg.id_user === sessionStorage.getItem("jwtToken")) { setMess( "for the client with id " + msg.id_user + " the max energy for device with ID " + msg.id_device + " has been EXCEDEED with " + msg.diferenta ); setOpen(true); } console.log(msg.id_user); }); }); }
问题分析与解决方案
核心问题:请求头传递格式错误
原代码中错误地将headers包装在嵌套对象headersAuth中传递给stompClient.connect,导致服务器无法正确识别Authorization头——这是浏览器返回401的直接原因。Postman中你应该是直接正确设置了请求头,所以连接成功。
其他潜在问题
- 用户ID判断逻辑错误:直接用JWT Token与
msg.id_user比较,Token本身不是用户ID,需解析JWT Payload获取用户标识。 - 缺少错误回调:未添加连接失败的回调函数,无法直观排查连接错误细节。
修正后的代码
async function connect() { var socket = new SockJS("http://localhost:8080/api/websocket"); let stompClient = Stomp.over(socket); const token = sessionStorage.getItem("jwtToken"); // 先验证Token是否存在 if (!token) { console.error("sessionStorage中未找到JWT Token"); return; } const headers = { Authorization: "Bearer " + token, }; console.log("连接请求头:", headers); // 直接传递headers对象,而非嵌套结构 stompClient.connect(headers, function (frame) { console.log("连接成功:", frame); stompClient.subscribe("/topic/events", function (messageOutput) { const msg = JSON.parse(messageOutput.body); // 解析JWT获取用户ID(需根据实际Payload字段调整) const parsedToken = parseJwt(token); const userId = parsedToken?.id_user; if (msg.id_user === userId) { setMess( `客户端ID ${userId} 的设备ID ${msg.id_device} 已超出最大能耗,超出值:${msg.diferenta}` ); setOpen(true); } console.log("收到消息目标用户ID:", msg.id_user); }); }, function(error) { // 添加错误回调,便于排查问题 console.error("连接失败:", error); }); } // 辅助函数:解析JWT Payload function parseJwt(token) { try { return JSON.parse(atob(token.split('.')[1])); } catch (e) { console.error("JWT解析失败:", e); return null; } }
额外验证步骤
- 在浏览器开发者工具的网络面板中,查看SockJS发起的请求,确认
Authorization头是否正确携带。 - 验证
sessionStorage中的jwtToken是否有效(未过期、签名正确)。
内容的提问来源于stack exchange,提问作者Mihalache Rares
相关产品推荐
相关产品推荐

