You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS中如何防止第三方连接WebSocket(使用WS模块)

如何为WS模块的WebSocket添加安全防护,仅允许指定域名访问

针对你用ws模块搭建WebSocket服务,想要限制只有自己的mydomain.com域名能连接并读取数据的需求,我整理了几个实用的方案,结合你的代码来具体说明:


1. 检查Origin请求头(基础防护)

浏览器发起WebSocket连接时,会自动带上Origin请求头,标识请求来自哪个域名。我们可以在服务端验证这个头,只允许指定域名的请求建立连接。

修改你的服务端代码:

var WebSocketServer = require('ws').Server;
wss = new WebSocketServer({ port: 8000 });

wss.on('connection', function (ws, req) {
  // 获取请求头里的Origin
  const origin = req.headers.origin;
  // 允许的域名列表,这里只放你的域名
  const allowedOrigins = ['https://mydomain.com'];
  
  // 验证Origin是否在允许列表里
  if (!allowedOrigins.includes(origin)) {
    ws.close(403, 'Forbidden: Unauthorized origin');
    return;
  }

  // 后续正常的连接处理逻辑
  ws.on('message', function(message) {
    console.log('Received:', message);
  });
});

⚠️ 注意:这个方法只能防普通浏览器请求,恶意客户端可以伪造Origin头绕过,所以只能作为基础防护,不能单独依赖。

2. 使用API密钥/令牌验证(更可靠)

可以在客户端连接时带上一个预定义的密钥,服务端验证通过后才允许建立连接。

服务端修改:

var WebSocketServer = require('ws').Server;
wss = new WebSocketServer({ port: 8000 });

const VALID_API_KEY = 'your-secret-api-key-here'; // 自己设置一个安全的密钥

wss.on('connection', function (ws, req) {
  // 从URL参数里获取API密钥
  const urlParams = new URLSearchParams(req.url.slice(1));
  const apiKey = urlParams.get('apiKey');

  if (!apiKey || apiKey !== VALID_API_KEY) {
    ws.close(403, 'Forbidden: Invalid API key');
    return;
  }

  // 验证通过后的逻辑
});

客户端修改:

// 连接时带上API密钥参数
var wss = new WebSocket('wss://mydomain.com?apiKey=your-secret-api-key-here');
wss.onmessage = function(e) {
  var data = JSON.parse(e.data);
  // 处理数据
};

建议把密钥存在客户端的环境变量或者安全的存储里,不要硬编码在公开的代码中(比如可以通过后端渲染页面时注入)。

3. 结合HTTP会话验证(如果网站有用户登录)

如果你的网站已经有用户登录系统,可以利用已有的HTTP会话来验证WebSocket连接。比如用户登录后会有一个会话ID存在Cookie里,WebSocket连接时会自动带上Cookie,服务端可以验证这个会话是否有效。

服务端示例(假设用express-session):

const express = require('express');
const session = require('express-session');
const WebSocketServer = require('ws').Server;

const app = express();
// 配置session
app.use(session({
  secret: 'your-session-secret',
  resave: false,
  saveUninitialized: true
}));

// 先启动HTTP服务器,再挂载WebSocket
const server = app.listen(8000);
const wss = new WebSocketServer({ server });

wss.on('connection', function (ws, req) {
  // 利用express-session的中间件解析Cookie里的会话
  session({
    secret: 'your-session-secret',
    resave: false,
    saveUninitialized: true
  })(req, {}, () => {
    // 检查会话是否有效,比如是否有用户信息
    if (!req.session.user) {
      ws.close(403, 'Forbidden: Not authenticated');
      return;
    }

    // 验证通过后的逻辑
  });
});

这种方式适合有用户体系的网站,能确保只有登录后的用户(且来自你的域名)才能连接。

4. 启用WSS(WebSocket Secure)

一定要用wss://而不是ws://,也就是通过HTTPS来传输WebSocket数据。WSS会加密传输的数据,防止中间方窃听或篡改,同时也能让浏览器更严格地验证Origin(非加密的ws可能被某些浏览器忽略Origin验证)。

你需要在服务端配置SSL证书,修改WebSocket服务器的创建代码:

const fs = require('fs');
const WebSocketServer = require('ws').Server;

const serverOptions = {
  cert: fs.readFileSync('/path/to/your/cert.pem'),
  key: fs.readFileSync('/path/to/your/private-key.pem')
};

// 创建HTTPS服务器,再挂载WebSocket
const httpsServer = require('https').createServer(serverOptions);
const wss = new WebSocketServer({ server: httpsServer });

httpsServer.listen(8000);

总结

  • 基础防护用Origin验证,快速实现但有局限性;
  • 更可靠的用API密钥或会话验证;
  • 必须启用WSS来加密传输,防止数据被窃听。

内容的提问来源于stack exchange,提问作者ToneCat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:01:47