我试图让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请求。
我写了一个简单的基于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说http。
编辑添加(4/6/2015)
对于使用AWS的系统,您最好使用EC2弹性负载均衡器来处理SSL终止,并允许常规HTTP通信到您的EC2 web服务器。为了进一步提高安全性,请设置安全组,以便只允许ELB向EC2实例发送HTTP流量,这将防止外部未加密的HTTP流量攻击您的计算机。
在让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并相应地创建服务器。另外,确保您尝试使用的端口实际上允许入站流量。
这就是我的工作方式。所使用的重定向也将重定向所有正常的http。
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const http = require('http');
const app = express();
var request = require('request');
//For https
const https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('certificates/private.key'),
cert: fs.readFileSync('certificates/certificate.crt'),
ca: fs.readFileSync('certificates/ca_bundle.crt')
};
// API file for interacting with MongoDB
const api = require('./server/routes/api');
// Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Angular DIST output folder
app.use(express.static(path.join(__dirname, 'dist')));
// API location
app.use('/api', api);
// Send all other requests to the Angular app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
app.use(function(req,resp,next){
if (req.headers['x-forwarded-proto'] == 'http') {
return resp.redirect(301, 'https://' + req.headers.host + '/');
} else {
return next();
}
});
http.createServer(app).listen(80)
https.createServer(options, app).listen(443);
在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)。
您还可以使用node-forge生成自签名证书
在下面的代码中,在启动时生成一个新证书,这意味着每次重新启动服务器时都将获得一个新证书。
const https = require('https')
const express = require('express')
const forge = require('node-forge')
;(function main() {
const server = https.createServer(
generateX509Certificate([
{ type: 6, value: 'http://localhost' },
{ type: 7, ip: '127.0.0.1' }
]),
makeExpressApp()
)
server.listen(8443, () => {
console.log('Listening on https://localhost:8443/')
})
})()
function generateX509Certificate(altNames) {
const issuer = [
{ name: 'commonName', value: 'example.com' },
{ name: 'organizationName', value: 'E Corp' },
{ name: 'organizationalUnitName', value: 'Washington Township Plant' }
]
const certificateExtensions = [
{ name: 'basicConstraints', cA: true },
{ name: 'keyUsage', keyCertSign: true, digitalSignature: true, nonRepudiation: true, keyEncipherment: true, dataEncipherment: true },
{ name: 'extKeyUsage', serverAuth: true, clientAuth: true, codeSigning: true, emailProtection: true, timeStamping: true },
{ name: 'nsCertType', client: true, server: true, email: true, objsign: true, sslCA: true, emailCA: true, objCA: true },
{ name: 'subjectAltName', altNames },
{ name: 'subjectKeyIdentifier' }
]
const keys = forge.pki.rsa.generateKeyPair(2048)
const cert = forge.pki.createCertificate()
cert.validity.notBefore = new Date()
cert.validity.notAfter = new Date()
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1)
cert.publicKey = keys.publicKey
cert.setSubject(issuer)
cert.setIssuer(issuer)
cert.setExtensions(certificateExtensions)
cert.sign(keys.privateKey)
return {
key: forge.pki.privateKeyToPem(keys.privateKey),
cert: forge.pki.certificateToPem(cert)
}
}
function makeExpressApp() {
const app = express()
app.get('/', (req, res) => {
res.json({ message: 'Hello, friend' })
})
return app
}
这个答案与Setthase非常相似,但它是用于LetsEncrypt (Ubuntu)的
// Dependencies
const fs = require('fs');
const http = require('http');
const https = require('https');
const express = require('express');
const app = express();
// Certificate
const privateKey = fs.readFileSync('/etc/letsencrypt/live/yourdomain.com/privkey.pem', 'utf8');
const certificate = fs.readFileSync('/etc/letsencrypt/live/yourdomain.com/cert.pem', 'utf8');
const ca = fs.readFileSync('/etc/letsencrypt/live/yourdomain.com/chain.pem', 'utf8');
const credentials = {
key: privateKey,
cert: certificate,
ca: ca
};
app.use((req, res) => {
res.send('Hello there !');
});
// Starting both http & https servers
const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);
httpServer.listen(80, () => {
console.log('HTTP Server running on port 80');
});
httpsServer.listen(443, () => {
console.log('HTTPS Server running on port 443');
});
您可能会遇到:EACCES:权限被拒绝,打开'/etc/letsencrypt/live/yourdeomain.com/privkey.pem'
答案在这里:让我们加密SSL不能开始“错误:EACCES:权限被拒绝,打开'/etc/letsencrypt/live/domain.net/privkey.pem'”
对我有用的是在ubuntu的ssh终端
获取用户whoami
// Create group with root and nodeuser as members
$ sudo addgroup nodecert
$ sudo adduser ubuntu nodecert
$ sudo adduser root nodecert
// Make the relevant letsencrypt folders owned by said group.
$ sudo chgrp -R nodecert /etc/letsencrypt/live
$ sudo chgrp -R nodecert /etc/letsencrypt/archive
// Allow group to open relevant folders
$ sudo chmod -R 750 /etc/letsencrypt/live
$ sudo chmod -R 750 /etc/letsencrypt/archive
sudo reboot