如何使用 Express/Socket.io 在 Node.js 上使用 HTTPS

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31156884/
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 18:56:10  来源:igfitidea点击:

How to use HTTPS on Node.js using Express/Socket.io

node.jsexpresshttpssocket.io

提问by kovogel

Im trying to run my node server with https. I'm using express and socket.io.

我正在尝试使用 https 运行我的节点服务器。我正在使用 express 和 socket.io。

This is my code for https:

这是我的 https 代码:

var httpsPort = 443;
var privateKey = fs.readFileSync(mykeypath');
var certificate = fs.readFileSync(mycertificatepath');
var credentials = {key: privateKey, cert: certificate};
var https = require('https').Server(credentials,app);
var io = require('socket.io')(https);

https.listen(httpsPort, function(){
logger.info('listening on *:' + httpsPort);
});


app.get('/initGame', function (req,res){

var slots = require('./slots.json', 'utf8');
var userObject = {
    address : req.connection.remoteAddress,
    userAgent : req.headers['user-agent']
};
db.getPlayedGames(userObject,function(playedGames){
    logger.debug(playedGames);
    if(typeof playedGames == 'undefined' ){
        playedGames=0;
    }else{
        playedGames = playedGames.games_played;
    }
    var spinsLeft = 10-playedGames;
    res.json({
        spinsLeft: spinsLeft,
        slots: slots
    });
  });
});

on my client its the following:

在我的客户上,它的内容如下:

var myServer = "//" + document.domain + ":443";

$.get( myServer + "/initGame", function(data) {
    totalSpinsLeft = data.spinsLeft;
    $('#trysLeft').text(totalSpinsLeft);
    Seven.init(data.slots);
}).fail(function(){
    setTimeout(function(){
        $('#spinner2').text('Fehler bitte neu laden!');
    },3000);

});

Right now im getting the following exception on my server:

现在我在我的服务器上收到以下异常:

uncaughtException: Missing PFX or certificate + private key.

uncaughtException: 缺少 PFX 或证书 + 私钥。

EDIT: right now im getting

编辑:现在我得到

Bad Request

错误的请求

Your browser sent a request that this server could not understand. Reason: You're speaking plain HTTP to an SSL-enabled server port. Instead use the HTTPS scheme to access this URL, please.

您的浏览器发送了此服务器无法理解的请求。原因:您对启用 SSL 的服务器端口使用纯 HTTP。请改用 HTTPS 方案访问此 URL。

回答by Wilson

It is hard to test your example without your key and cert files instead I am going to provide an example where I am using Express, socket.io, and https.

如果没有您的密钥和证书文件,很难测试您的示例,相反,我将提供一个示例,其中我使用 Express、socket.io 和 https。

First I will create the key and cert files, so inside a directory run the following commands from your terminal:

首先,我将创建密钥和证书文件,因此在目录中从终端运行以下命令:

The command below it is going to generate a file containing an RSA key.

下面的命令将生成一个包含 RSA 密钥的文件。

$ openssl genrsa 1024 > file.pem

Here you will be asked to input data but you can leave blank pressing enter until the crs.pem is generated.

在这里,您将被要求输入数据,但您可以按 Enter 键保留空白,直到生成 crs.pem。

$ openssl req -new -key file.pem -out csr.pem

Then a file.crt file will be created containing an SSL certificate.

然后将创建一个包含 SSL 证书的 file.crt 文件。

$ openssl x509 -req -days 365 -in csr.pem -signkey file.pem -out file.crt


So in my app.jsfile where I am setting and starting the server notice that I am using the files file.pemand file.crtgenerated in the last step:

因此,在我app.js设置和启动服务器的文件中file.pem,请注意我正在使用这些文件并file.crt在最后一步生成:

var fs = require('fs');
var https = require('https');

var express = require('express');
var app = express();

var options = {
  key: fs.readFileSync('./file.pem'),
  cert: fs.readFileSync('./file.crt')
};
var serverPort = 443;

var server = https.createServer(options, app);
var io = require('socket.io')(server);

app.get('/', function(req, res) {
  res.sendFile(__dirname + '/public/index.html');
});

io.on('connection', function(socket) {
  console.log('new connection');
  socket.emit('message', 'This is a message from the dark side.');
});

server.listen(serverPort, function() {
  console.log('server up and running at %s port', serverPort);
});

and then my public/index.htmlwhere I am consuming the server:

然后我public/index.html在哪里使用服务器:

<!doctype html>
<html>

  <head>

  </head>
  <body>
    <h1>I am alive!!</h1>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.js"></script>

    <script>
      var URL_SERVER = 'https://localhost:443';
      var socket = io.connect(URL_SERVER);

      socket.on('message', function(data) {
        alert(data);
      });
    </script>
  </body>

</html>

then finally if you access from the browser at https://localhost, you will see an alert with a message that is coming from the websocket server.

最后,如果您从 浏览器访问https://localhost,您将看到一个警告,其中包含来自 websocket 服务器的消息。

回答by emonik

This is how I managed to set it up with express:

这就是我设法使用 express 进行设置的方式:

var fs = require( 'fs' );
var app = require('express')();
var https        = require('https');
var server = https.createServer({
    key: fs.readFileSync('./test_key.key'),
    cert: fs.readFileSync('./test_cert.crt'),
    ca: fs.readFileSync('./test_ca.crt'),
    requestCert: false,
    rejectUnauthorized: false
},app);
server.listen(8080);

var io = require('socket.io').listen(server);

io.sockets.on('connection',function (socket) {
    ...
});

app.get("/", function(request, response){
    ...
})

I hope that this will save someone's time.

我希望这会节省某人的时间。