node.js 如何设置 socket.io origins 以限制连接到一个 url

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15771805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 14:04:39  来源:igfitidea点击:

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

javascriptnode.jssocket.io

提问by Michael Moeller

We have one html site and one node.js server which serves that website. The website and the server exchange data using socke.io. We found this in the documentation:

我们有一个 html 站点和一个为该网站提供服务的 node.js 服务器。网站和服务器使用 socke.io 交换数据。我们在文档中发现了这一点:

origins defaults to*:*The origins that are allowed to connect to the Socket.IO server.

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

Our html.site is on http://questionexample.com/page1. Only this site may connect to our server.(But everyone may connect to that website.) How do we have to set the origins?

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

回答by Oleg

If you dig into Socket.io source code, you will find such lines:

如果您深入研究 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);

As you can see Socket.io takes origin (or referer) that came from the client, retrieves domain name and port, and compares with the originsoption you specified.

如您所见,Socket.io 获取来自客户端的来源(或引用者),检索域名和端口,并与origins您指定的选项进行比较。

So the valid originsvalues are (*means "any"):

所以有效值origins是(*意味着“任何”):

  • testsite.com:80
  • http://testsite.com:80
  • http://*:8080
  • *:8080
  • testsite.com:* http://someotherdomain.com:8080(multiple origins separated by space)
  • testsite.com:*/somepath(socket.io will ignore /somepath)
  • *:*
  • testsite.com:80
  • http://testsite.com:80
  • http://*:8080
  • *:8080
  • testsite.com:* http://someotherdomain.com:8080(多个原点以空格分隔)
  • testsite.com:*/somepath(socket.io 将忽略 /somepath)
  • *:*

And these are invalid (because no port number):

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

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

Also note that if you specify sub.testsite.comas origins value, the testsite.comwill be validorigin.

另请注意,如果您指定sub.testsite.com为 origins 值,testsite.com则将是有效的origin。

回答by Rob

I've had similar problem. Try run node in production mode NODE_ENV=production node app.js. I had that code (as recommended here):

我有过类似的问题。尝试在生产模式下运行节点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:*');
});

and Node rans in development mode so it simply couldn't work. After enabling production mode everything is ok.

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

I know that it is a little bit late answer but maybe someone else will use that

我知道答案有点晚,但也许其他人会使用它

回答by user3788685

For newer versions of socket.io(up to the current 2.2.0you need to set CORS origin as part of the server options.

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

Here is a very simple/basic config block for those who come looking without using express or anything other than the raw socket.io engine;

这是一个非常简单/基本的配置块,适合那些不使用 express 或原始 socket.io 引擎以外的任何东西的人;

// 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);

If you want to restrict the origin then you should use origins: 'host-name:port-num'as required.

如果要限制来源,则应origins: 'host-name:port-num'根据需要使用。

回答by kartik bansal

You can do something like this on server side with url of your site

您可以使用您网站的网址在服务器端执行类似操作

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

回答by csicar

I think io.set('origins', http://questionexample.com/page1)should do it

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