如何设置socket.IO起源限制连接到一个url

how to set socket.io origins to restrict connections to one url

本文关键字:连接 url 一个 起源 何设置 设置 socket IO      更新时间:2023-09-26

我们有一个html网站和一个为该网站服务的node.js服务器。网站和服务器使用socket .io交换数据。我们在文档中找到了这个:

origins默认为 *:*允许连接到套接字的源。IO服务器。

我们的html。网站在http://questionexample.com/page1上。只有这个网站可以连接到我们的服务器。(但每个人都可以连接到那个网站。)我们要如何设置原点呢?

如果您深入了解Socket。IO源代码,你会发现这样的行:

var origin = request.headers.origin || request.headers.referer
  , origins = this.get('origins');
...
var parts = url.parse(origin);
parts.port = parts.port || 80;
var ok =
  ~origins.indexOf(parts.hostname + ':' + parts.port) ||
  ~origins.indexOf(parts.hostname + ':*') ||
  ~origins.indexOf('*:' + parts.port);

可以看到Socket。IO接收来自客户端的origin(或referer),检索域名和端口,并与您指定的origins选项比较。

所以有效的origins值是(*表示"任何"):

  • testsite.com:80
  • http://testsite.com:80
  • http://*:8080
  • *:8080
  • testsite.com:* http://someotherdomain.com:8080 (多个原点以空格分隔)
  • testsite.com:*/somepath (socket。
  • *:*

这些都是无效的(因为没有端口号):

  • testsite.com
  • http://testsite.com
  • http://testsite.com/somepath

还请注意,如果您指定sub.testsite.com作为原点值,testsite.com将是有效的原点。

我也遇到过类似的问题。尝试在生产模式NODE_ENV=production node app.js下运行节点。我有这样的代码(在这里推荐):

io.configure('production', function(){
    console.log("Server in production mode");
    io.enable('browser client minification');  // send minified client
    io.enable('browser client etag'); // apply etag caching logic based on version number
    io.enable('browser client gzip'); // the file
    io.set('log level', 1);           // logging
    io.set('transports', [            // all transports (optional if you want flashsocket)
        'websocket'
        , 'flashsocket'
        , 'htmlfile'
        , 'xhr-polling'
        , 'jsonp-polling'
    ]);
io.set('origins', 'http://questionexample.com/page1:*');
});

和Node在开发模式下运行,所以它根本无法工作。启用生产模式后,一切正常。

我知道这个答案有点晚了但是也许其他人会用

对于较新版本的socket.io(到当前4.x.x),您需要将CORS origin设置为服务器选项的一部分。

CORS现在被分离到自己的模块中-详细信息请参阅自述文件

默认配置为;

{
  "origin": "*",
  "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
  "preflightContinue": false,
  "optionsSuccessStatus": 204
}

和限制一个站点使用任何子域;

cors: {
        origin: [/'.example'.com$/],
        methods: ["GET", "POST"]
        }

这里是一个非常简单/基本的配置块,为那些没有使用express或任何其他原始套接字的人。io引擎;编辑:socket.io版本3更新。

// Options for socket.io => 3.0.0
var options = {
        allowUpgrades: true,
        transports: [ 'polling', 'websocket' ],
        pingTimeout: 9000,
        pingInterval: 3000,
        cookie: 'mycookie',
        httpCompression: true,
        cors: '*:*' <---- Allow any origin here [NOTE THE NAME CHANGE]
};

旧版本使用;

// Options for socket.io > 1.0.0
var options = {
        allowUpgrades: true,
        transports: [ 'polling', 'websocket' ],
        pingTimeout: 9000,
        pingInterval: 3000,
        cookie: 'mycookie',
        httpCompression: true,
        origins: '*:*' <---- Allow any origin here
};
io = require('socket.io')(8010, options);

你可以在服务器端这样做你的网站url

  if (origin !== 'https://foo.example.com') {
    return callback('origin not allowed', false);
  }
  callback(null, true);
});

我认为io.set('origins', http://questionexample.com/page1)应该这样做