无法连接到本地 Node.js 安全 WebSocketServer

Posted

技术标签:

【中文标题】无法连接到本地 Node.js 安全 WebSocketServer【英文标题】:Can't connect to local Node.js secure WebSocketServer 【发布时间】:2019-06-06 16:19:00 【问题描述】:

为了测试 javascript / html5 应用程序,我使用 node.js 和 ws package 创建了一个本地 WebSocketServer。我想通过 SSL/TLS 使用安全 websockets (wss)。

密钥和证书由 OpenSSL 在本地创建用于测试目的(自签名证书)。

客户端只是尝试使用本机 WebSocket 对象连接到(本地)https 服务器:

var ws = new Websocket('wss://localhost:8080');

问题是,没有浏览器(Firefox、Chrome、Edge)可以连接到服务器,它们都给我不同的错误消息。

火狐:

Firefox 无法连接到 wss 的服务器:// localhost: 8080 /。

铬:

ws_client.js:7 WebSocket 连接到 'wss://localhost:8080/' 失败: 连接建立错误:net::ERR_CERT_AUTHORITY_INVALID

边缘:

SCRIPT12017:SCRIPT12017:WebSocket 错误:SECURITY_ERR,跨区域 不允许连接

我在 OpenSSL(轻量级,最新版本)中创建了证书和密钥,如下所示:

openssl req -new -x509 -nodes -out server.crt -keyout server.key

(source)

我检查了几乎所有关于这个(和类似)主题的问题,例如this question,但他们都无法提供解决方案。

请不要将此问题标记为重复,因为所有类似的问题都包含略有不同的问题!

服务器代码:

var fs = require('file-system');

var pkey = fs.readFileSync('server.key', 'utf8');
var crt = fs.readFileSync('server.crt', 'utf8');

var credentials =  key: pkey, cert: crt ;
var https = require('https');

var httpsServer = https.createServer(credentials);
httpsServer.listen(8080);

var WebSocketServer = require('ws').Server;

var wss = new WebSocketServer(
    server: httpsServer
);

wss.on('connection', function connection(ws) 
    ws.on('message', function incoming(message) 
        console.log('received: %s', message);
        ws.send('reply from server : ' + message)
    );

);

我尝试了另一个代码作为服务器,但出现同样的错误:

const WebSocketServer = require('ws').Server; 
var fs = require('file-system');

var ws_cfg = 
    ssl: true,
    port: 8080,
    ssl_key: 'server.key',
    ssl_cert: 'server.crt'
;

var processRequest = function(req, res) 
    console.log('Request received');
;

var httpServ = require('https');

var app = httpServ.createServer(
    key: fs.readFileSync(ws_cfg.ssl_key, 'utf8', (error) => 
        console.log('Error reading file');
    ),
    cert: fs.readFileSync(ws_cfg.ssl_cert, 'utf8',  (error) => 
        console.log('Error reading file');
    )
, processRequest).listen(ws_cfg.port, function()
    console.log('Server running');
);



var wss = new WebSocketServer( server: app, port: 8080, host: 'localhost', domain: 'localhost' );



wss.on('connection', function (ws) 

    console.log('Connected to a client');

    ws.on('message', function (message) 

        console.log('MSG received: ' + message);

    );

);

还有一件事。总是,如果我在服务器代码中添加console.log(wss);,输出看起来像这样:

WebSocketServer 
  domain: null,
  ...some more stuff...
  ...cert key etc....
  host: null,
  path: null,
  port: null  

主机、域和端口设置为null。我尝试了一切将其设置为 localhost:8080,但没有任何结果。我认为这可能是所有问题的根源,但找不到方法。如果有人知道这个问题的答案,我将不胜感激。

(使用不安全的 'ws' 协议 ('ws://localhost:8080') 以连接到本地 node.js http 服务器有效,但我想尽可能真实地测试应用程序并且使用安全连接。)

【问题讨论】:

您也可以尝试使用 127.0.0.1:8080 代替 localhost 【参考方案1】:

-- 这不是答案,只是我的解决方法--

对于任何有同样问题的人,这是我所做的:

服务器代码应该是:

const fs = require('fs');
const https = require('https');
const WebSocket = require('ws');

const server = new https.createServer(
  cert: fs.readFileSync('localcert.cert'),   //what ever you're files are called
  key: fs.readFileSync('localkey.key')
);

const wss = new WebSocket.Server( server );  // !

wss.on('connection', function connection(ws) 
  ws.on('message', function incoming(message) 
    console.log('MSG received: %s', message);
  );

  ws.send('Hi to client');
);


server.listen(8080);

目前只能在谷歌浏览器中使用,在火狐中仍然无法连接。

在谷歌浏览器中输入chrome://flags/#allow-insecure-localhost并启用。

【讨论】:

我所做的是设置一个全局布尔值,用于检查服务器是否从我的本地计算机启动以及是否启动。将服务器创建为 http 而不是 https。这适用于 Firefox 和 chrome。 您在哪个 url 上使用 Web 客户端?和websocket有区别吗?【参考方案2】:

尝试在您正在使用的系统上添加自签名证书或生成的 CA 以受信任。

【讨论】:

如果你让它更肯定,那么这可以被认为是一个答案。不要在答案中添加问号。

以上是关于无法连接到本地 Node.js 安全 WebSocketServer的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用安全 WebSocket (wss) 连接到本地 Windows 服务应用程序吗

当应用程序在本地运行时,Node.js 能够连接到 MySQL 容器,但当应用程序在容器中运行时无法连接

Node.js 无法从 Heroku 连接到 mongodb 3 到 Mongolab:SCRAM-SHA-1

节点服务器无法连接到 postgres db

AWS ELB - 服务 A 无法连接到同一安全组中的服务 B

如何将 plunker 连接到本地 Node.js 服务器?