【问题标题】:How to use HTTPS on Node.js using Express/Socket.io如何使用 Express/Socket.io 在 Node.js 上使用 HTTPS
【发布时间】:2015-07-01 08:58:24
【问题描述】:

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

这是我的 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
    });
  });
});

在我的客户端上是:

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

});

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

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

编辑:现在我得到了

错误请求

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

【问题讨论】:

    标签: node.js express https socket.io


    【解决方案1】:

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

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

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

    $ openssl genrsa 1024 > file.pem
    

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

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

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

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

    所以在我设置和启动服务器的app.js 文件中,请注意我正在使用上一步生成的文件file.pemfile.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);
    });
    

    然后是我的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>
    

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

    【讨论】:

    • 也为我工作,非常感谢。我注意到您将 (dot)Server 更改为 (dot)createServer - 有什么原因吗?我也换了我的,效果很好。
    • 看起来没有区别,看看这个答案关于你的疑问。 stackoverflow.com/questions/26921117/…
    • 如何在没有可怕的键警告的情况下实现这一点?另外,这适用于任何端口吗?还是我必须使用 443?如果我们有多个使用 socket.io 的服务并且需要不同的端口怎么办?会有cors问题吗?
    • 请问您是如何让客户端上的 require() 函数可用的?
    • @DanL 如果你引用app.js文件,它正在服务器端运行。
    【解决方案2】:

    这就是我设法用 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){
        ...
    })
    

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

    【讨论】:

    • 您好 emonik,您如何获得 test_key.key、test_cert.crt 和 test_cs.crt 文件?
    • 我使用让我们加密为 ssl。
    • @ClaesGustavsson :使用它来加密var server = https.createServer({ key: fs.readFileSync('privkey.pem'), cert: fs.readFileSync('fullchain.pem') },app);
    • Emonik,谢谢,但我仍然收到此错误? 46.22.120.82:3000/socket.io/socket.io.jsnet::ERR_INSECURE_RESPONSE。我像这样链接:
    • 在我的 server.js 文件中我有这个: var server = https.createServer({ key: fs.readFileSync('C:/Users/kund-admin/AppData/Roaming/letsencrypt-win -simple/httpsacme-v01.api.letsencrypt.org/manmade.se-key.pem'),证书:fs.readFileSync('C:/Users/kund-admin/AppData/Roaming/letsencrypt-win-simple/httpsacme -v01.api.letsencrypt.org/manmade.se-chain.pem') },app); var io = require('socket.io').listen(server);
    猜你喜欢
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 2015-04-28
    • 2017-05-01
    • 1970-01-01
    • 2015-07-23
    相关资源
    最近更新 更多