在 node.js 中使用 socket.io 设置服务器-服务器 SSL 通信

Posted

技术标签:

【中文标题】在 node.js 中使用 socket.io 设置服务器-服务器 SSL 通信【英文标题】:Setup Server-Server SSL communication using socket.io in node.js 【发布时间】:2014-03-06 05:53:06 【问题描述】:

我正在尝试通过 ssl 连接使用 socket.io 设置服务器到服务器的链接。这是我的例子:

/**
 * Server
 */


var app = require('express')();
var config = require('./config');
var https = require('https');
var http = require('http');
var fs = require('fs');
var server = https.createServer(key: fs.readFileSync(config.ssl.key), cert: fs.readFileSync(config.ssl.cert), passphrase: config.ssl.passphrase, app);
//var server = http.createServer(app);
var io = require('socket.io').listen(server);

server.listen(config.port);

app.get('/', function (req, res) 
    res.send('Server');
  //res.sendfile(__dirname + '/index.html');
);

io.sockets.on('connection', function (socket) 
  socket.emit('news',  hello: 'world' );
  socket.on('my other event', function (data) 
    console.log(data);
  );
);



/**
 * Client
 */


var io = require('socket.io-client');
//var socket = io.connect('http://localhost', port: 8088);
var socket = io.connect('https://localhost', secure: true, port: 8088);
  socket.on('connect', function()
    socket.on('event', function(data));
    socket.on('disconnect', function());
  );

代码在没有 SSL 的情况下运行良好。我怀疑这可能是我的自签名证书没有被接受,但我不知道如何让客户接受它。

我可以接受自签名 SSL 证书,还是可以采取其他方法?

【问题讨论】:

经过一番挖掘,我发现添加:require('https').globalAgent.options.rejectUnauthorized = false;在客户端中的“var socket”修复问题之前 【参考方案1】:

虽然上述所有解决方案都集中在rejectUnauthorized=false,但我想提出一个替代方案。

const https = require('https');
const rootCas = require('ssl-root-cas').create();
rootCas.addFile('cert/ca.crt');
https.globalAgent.options.ca = rootCas; // optional

const io = require("socket.io-client");
var socket = io.connect("https://...",  agent: https.globalAgent );

【讨论】:

【参考方案2】:

以前的答案对我没有用。 require('https').globalAgent 始终是 undefined

做了一些搜索,在文档 (https://nodejs.org/api/tls.html) 中找到了 rejectUnauthorized 参数。不确定它是否与 SocketIO 有关,但它似乎可以与自签名证书一起使用:

var socket = io.connect('//yourhost:8000', secure: true, rejectUnauthorized: false)

secure: true 可能是可选的,但无论如何我都喜欢强制执行。

【讨论】:

【参考方案3】:

我必须在客户端上做一些不同的事情才能让它工作,通过手动告诉 socket.io 也使用该代理(secure: true 隐含在https: 中)。这里是:

// Client
var io = require('socket.io-client');
var https = require('https');
https.globalAgent.options.rejectUnauthorized = false;
var socket = io.connect('https://localhost:3210/',  agent: https.globalAgent );
socket.on('connect', function() console.log('connected'); );

这是使用 socket.io v1.0.2。

或者,我在以下方面也取得了成功,正如这里所指出的:Socket.io + SSL + self-signed CA certificate gives error when connecting

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
var io = require('socket.io-client');
var socket = io.connect('https://localhost:3210/');
socket.on('connect', function() console.log('connected'); );

【讨论】:

工作完美!我不使用自签名证书,但我希望在对我的开发盒进行本地单元测试时能够忽略我的认证问题。这成功了!谢谢 经过一整天的搜索和尝试,您的第一个解决方案对我有用。第二个没有工作。谢谢!【参考方案4】:

经过一番搜索,在客户端中添加它就可以了:

require('https').globalAgent.options.rejectUnauthorized = false;

/**
 * Client
 */


var io = require('socket.io-client');
//var socket = io.connect('http://localhost', port: 8088);

require('https').globalAgent.options.rejectUnauthorized = false; 

var socket = io.connect('https://localhost', secure: true, port: 8088);
  socket.on('connect', function()
    socket.on('event', function(data));
    socket.on('disconnect', function());
  );

【讨论】:

对于新版本的 node.js,您还必须添加 process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;

以上是关于在 node.js 中使用 socket.io 设置服务器-服务器 SSL 通信的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 和 socket.io 的混淆

在 node.js 中使用 socket.io 通过 webrtc 广播实时音频

在 Heroku 上使用集群和 socket.io-redis 扩展 node.js socket.io@1.*.*

使用 socket.io 在 Node.js 中使用 MySql 数据库进行 HTML5 页面日志记录

在visual studio node.js项目中使用socket.io

Node.js、多线程和 Socket.io