简体   繁体   English

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

[英]how to set socket.io origins to restrict connections to one url

We have one html site and one node.js server which serves that website.我们有一个 html 站点和一个为该网站提供服务的 node.js 服务器。 The website and the server exchange data using socke.io.网站和服务器使用 socke.io 交换数据。 We found this in the documentation:我们在文档中发现了这一点:

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 .我们的 html.site 位于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?只有这个站点可以连接到我们的服务器。(但每个人都可以连接到那个网站。)我们如何设置起源?

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 origins option you specified.正如您所看到的,Socket.io 获取来自客户端的 origin(或referer),检索域名和端口,并与您指定的origins选项进行比较。

So the valid origins values 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:* http://someotherdomain.com:8080 (多个来源以空格分隔)
  • testsite.com:*/somepath (socket.io will ignore /somepath) testsite.com:*/somepath (socket.io 会忽略 /somepath)
  • *:*

And these are invalid (because no port number):这些是无效的(因为没有端口号):

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

Also note that if you specify sub.testsite.com as origins value, the testsite.com will be valid origin.另请注意,如果您指定sub.testsite.com作为 origins 值,则testsite.com将是有效的origin。

I've had similar problem.我有过类似的问题。 Try run node in production mode NODE_ENV=production node app.js .尝试在生产模式下运行 node NODE_ENV=production node app.js I had that code ( as recommended here ):我有那个代码( 正如这里推荐的那样):

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.并且 Node 在开发模式下运行,所以它根本无法工作。 After enabling production mode everything is ok.启用生产模式后一切正常。

I know that it is a little bit late answer but maybe someone else will use that我知道答案有点晚,但也许其他人会使用它

For newer versions of socket.io (up to the current 4.xx you need to set CORS origin as part of the server options.对于较新版本的socket.io (直到当前4.xx您需要将 CORS 源设置为服务器选项的一部分。

CORS is now split off into its own module - See the readme for details. CORS 现在被拆分成它自己的模块 - 有关详细信息,请参阅自述文件

The default config is;默认配置是;

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

and to restrict to one site with any subdomain use;并限制在一个站点使用任何子域;

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

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 引擎以外的任何东西的人; Edit: Updated for version 3 of socket.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]
};

Older versions use;旧版本使用;

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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM