在express.js上启用HTTPS

我试图让HTTPS的express.js工作节点,我无法弄清楚。

这是我的app.js代码。

 var express = require('express'); var fs = require('fs'); var privateKey = fs.readFileSync('sslcert/server.key'); var certificate = fs.readFileSync('sslcert/server.crt'); var credentials = {key: privateKey, cert: certificate}; var app = express.createServer(credentials); app.get('/', function(req,res) { res.send('hello'); }); app.listen(8000); 

当我运行它,似乎只响应HTTP请求。

我写了简单的基于vanilla node.js的HTTPS应用程序:

 var fs = require("fs"), http = require("https"); var privateKey = fs.readFileSync('sslcert/server.key').toString(); var certificate = fs.readFileSync('sslcert/server.crt').toString(); var credentials = {key: privateKey, cert: certificate}; var server = http.createServer(credentials,function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }); server.listen(8000); 

而当我运行这个应用程序,它确实响应HTTPS请求。 请注意,我不认为fs结果上的toString()结果很重要,因为我已经使用了两者的组合,但仍然没有es bueno。


编辑添加:

对于生产系统,使用Nginx或HAProxy将请求代理到nodejs应用程序可能会更好。 你可以设置nginx来处理ssl请求,只要告诉你的节点app.js.

编辑添加(4/6/2015)

对于使用AWS的系统,最好使用EC2弹性负载平衡器来处理SSL终止,并允许定期向您的EC2 Web服务器发送HTTPstream量。 为了进一步提高安全性,请设置您的安全组,以便只允许ELB将HTTPstream量发送到EC2实例,这将防止外部未encryption的HTTPstream量撞击您的计算机。


在express.js(从版本3开始)你应该使用这个语法:

 var fs = require('fs'); var http = require('http'); var https = require('https'); var privateKey = fs.readFileSync('sslcert/server.key', 'utf8'); var certificate = fs.readFileSync('sslcert/server.crt', 'utf8'); var credentials = {key: privateKey, cert: certificate}; var express = require('express'); var app = express(); // your express configuration here var httpServer = http.createServer(app); var httpsServer = https.createServer(credentials, app); httpServer.listen(8080); httpsServer.listen(8443); 

通过这种方式,您可以将本地中间件提供给本地http / https服务器

如果您希望您的应用在低于1024的端口上运行,则需要使用sudo命令(不推荐)或使用反向代理(例如nginx,haproxy)。

我遇到了一个类似的问题,让SSL在端口443以外的端口上工作。在我的情况下,我有一个捆绑证书以及一个证书和一个密钥。 捆绑证书是一个拥有多个证书的文件,节点要求你将这些证书分解成一个数组的单独元素。

  var express = require('express'); var https = require('https'); var fs = require('fs'); var options = { ca: [fs.readFileSync(PATH_TO_BUNDLE_CERT_1), fs.readFileSync(PATH_TO_BUNDLE_CERT_2)], cert: fs.readFileSync(PATH_TO_CERT), key: fs.readFileSync(PATH_TO_KEY) }; app = express() app.get('/', function(req,res) { res.send('hello'); }); var server = https.createServer(options, app); server.listen(8001, function(){ console.log("server running at https://IP_ADDRESS:8001/") }); 

在app.js中,您需要指定https并相应地创build服务器。 此外,请确保您尝试使用的端口实际上允许入站stream量。

包括积分:

  1. SSL setup 1. In config/local.js 2. In config/env/production.js 

HTTP和WS处理

 1. The app must run on HTTP in development so we can easily debug our app. 2. The app must run on HTTPS in production for security concern. 3. App production HTTP request should always redirect to https. 

SSLconfiguration

在Sailsjs中有两种方法来configuration所有的东西,首先是在configuration文件夹中configuration每个人都有其单独的文件,(如关于设置数据库连接位于connections.js内)。 其次是在环境基础文件结构上configuration,每个环境文件在config / env文件夹中出现,每个文件包含特定env的设置。

*首先查看config / env文件夹,然后查看config / * .js

现在让我们在config / local.js中设置ssl

 var local = { port: process.env.PORT || 1337, environment: process.env.NODE_ENV || 'development' }; if(process.env.NODE_ENV == 'production') { local.ssl = { secureProtocol: 'SSLv23_method', secureOptions: require('constants').SSL_OP_NO_SSLv3, ca: require('fs').readFileSync(__dirname + '/path/to/ca.crt','ascii'), key: require('fs').readFileSync(__dirname + '/path/to/jsbot.key','ascii'), cert: require('fs').readFileSync(__dirname + '/path/to/jsbot.crt','ascii') }; local.port = 443; // This port should be different than your default port } module.exports = local; 

另外你也可以在config / env / production.js中添加这个。 (这段代码也展示了如何处理多个CARoot certi)

或者在production.js中

 module.exports = { port: 443, ssl: { secureProtocol: 'SSLv23_method', secureOptions: require('constants').SSL_OP_NO_SSLv3, ca: [ require('fs').readFileSync(__dirname + '/path/to/AddTrustExternalCARoot.crt', 'ascii'), require('fs').readFileSync(__dirname + '/path/to/COMODORSAAddTrustCA.crt', 'ascii'), require('fs').readFileSync(__dirname + '/path/to/COMODORSADomainValidationSecureServerCA.crt', 'ascii') ], key: require('fs').readFileSync(__dirname + '/path/to/jsbot.key', 'ascii'), cert: require('fs').readFileSync(__dirname + '/path/to/jsbot.crt', 'ascii') } }; 

http / https&ws / wssredirect

这里ws是Web Socket,wss代表Secure Web Socket,因为我们设置了ssl,那么现在http和ws这两个请求都变得安全并分别转换为https和wss。

从我们的应用程序有很多来源会收到像任何博客post,社交媒体post的请求,但我们的服务器只运行在https上,所以当任何请求来自HTTP它给客户端浏览器“本网站无法到达”错误。 我们损失了我们的网站stream量。 所以我们必须将http请求redirect到https,同样的规则允许websocket,否则套接字将失败。

因此,我们需要在端口80(http)上运行同一台服务器,并将所有请求转移到端口443(https)。 在提升服务器之前,首先编译config / bootstrap.js文件。 这里我们可以在端口80上启动我们的express服务器。

在config / bootstrap.js(创buildhttp服务器并将所有请求redirect到https)

 module.exports.bootstrap = function(cb) { var express = require("express"), app = express(); app.get('*', function(req,res) { if(req.isSocket) return res.redirect('wss://' + req.headers.host + req.url) return res.redirect('https://' + req.headers.host + req.url) }).listen(80); cb(); }; 

现在您可以访问http://www.yourdomain.com ,它将redirect到https://www.yourdomain.com