我创建了一个 Websocket(使用
ws
包)服务器来接收来自用户的消息。当消息发送时,它会直接发送到处理它的服务器,如下所示:
const WSS = new WebSocketServer({noServer: true});
WebServer.on('upgrade', async (req, socket, head) => {
// original 'req' has the data required for authentication
try {
await authenticateUser(req.headers); // Contains JWT token
} catch (error) {
console.log(`onupgrade error: ${error}`)
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
socket.destroy();
return;
}
WSS.on('connection', (ws, req) => {
ws.on('message', async (data, isBinary) => {
if(data.sentevent === 'Delivered') {
// Make an axios request but need to attach the req object from above
axios.post(`/api/v1/messagetracker`,{
messageid: 1234
});
}
})
});
});
Express 路线
/api/v1/messagetracker
使用中间件来验证用户身份,如下所示:
ExpressRouter.post('/api/v1/messagetracker',
Middlewares.authenticateUser,
async function (req, res, next) {
...
});
authenticateUser
只是解码 JWT 令牌:
async function authenticateUser(req, res, next) {
try {
req.UserDetails = await getUserData(req);
} catch (error) {
return res.status(error.code).json(error);
}
next();
}
如果路由是由客户端
POST
实现的,则 req
与包含 JWT 令牌的 cookie 一起存在。然而,当从节点服务器发出请求时,显然没有 JWT 令牌。
因此,我需要将从客户端发送到节点服务器(通过 Websocket 连接)的
req
传递到 Express 路由器。
有什么办法可以实现这个目标吗?
从 Websocket 请求中提取 JWT 令牌,因为初始 Websocket 连接(这是
req
回调函数中的 on('upgrade')
对象)在标头中包含 JWT 令牌,然后您可以提取此令牌并将其存储以供使用后续 WebSocket 消息。
从 websocket 服务器发出请求时,通过手动附加 JWT 令牌作为授权标头,将令牌附加到 axios 请求。
例如:
const WSS = new WebSocketServer({ noServer: true });
let jwtToken = null; // Store JWT token for the connection
WebServer.on('upgrade', async (req, socket, head) => {
try {
// Authenticate the user during the WebSocket upgrade
await authenticateUser(req.headers);
jwtToken = req.headers['authorization']; // Store the JWT token from the initial request
} catch (error) {
console.log(`onupgrade error: ${error}`);
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
socket.destroy();
return;
}
WSS.on('connection', (ws, req) => {
ws.on('message', async (data, isBinary) => {
if (data.sentevent === 'Delivered') {
// Make an axios request and attach the JWT token as a bearer token in the authorization header
axios.post(`/api/v1/messagetracker`, {
messageid: 1234
}, {
headers: {
'Authorization': jwtToken // Attach JWT token
}
})
.then(response => {
console.log('Message tracking success:', response.data);
})
.catch(error => {
console.error('Message tracking error:', error.response?.data || error.message);
});
}
});
});
});
然后检查 Express 路由上中间件中的
Authorization
标头并解码您的 JWT 令牌