我一直在尝试用我正在做的一个node.js项目来设置HTTPS。我基本上遵循了这个例子的node.js文档:

// curl -k https://localhost:8000/
var https = require('https');
var fs = require('fs');

var options = {
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};

https.createServer(options, function (req, res) {
  res.writeHead(200);
  res.end("hello world\n");
}).listen(8000);

现在,当我做的时候

curl -k https://localhost:8000/

我得到

hello world

像预期的那样。但如果我这样做了

curl -k http://localhost:8000/

我得到

curl: (52) Empty reply from server

回想起来,这似乎是显而易见的,它将以这种方式工作,但与此同时,最终访问我的项目的人不会输入https://yadayada,我希望所有的流量从他们访问网站的那一刻起就使用https。

我怎么能得到节点(和Express,因为这是我正在使用的框架)把所有传入的流量交给https,不管它是否被指定?我还没有找到任何解决这个问题的文档。或者只是假设在生产环境中,节点在它前面有一些东西(例如nginx)来处理这种重定向?

这是我第一次尝试web开发,所以如果这是显而易见的,请原谅我的无知。


当前回答

你可以使用express-force-https模块:

NPM install——save express-force-https

var express = require('express');
var secure = require('express-force-https');

var app = express();
app.use(secure);

其他回答

你可以使用express-force-https模块:

NPM install——save express-force-https

var express = require('express');
var secure = require('express-force-https');

var app = express();
app.use(secure);

从0.4.12开始,我们还没有使用Node的HTTP/HTTPS服务器在同一个端口上监听HTTP和HTTPS的真正干净的方法。

有些人通过让Node的HTTPS服务器(这也适用于Express.js)侦听443(或其他端口),并让一个小型http服务器绑定到80并将用户重定向到安全端口来解决这个问题。

如果你必须能够在一个端口上处理这两个协议,那么你需要把nginx, lighttpd, apache,或其他一些web服务器放在那个端口上,并充当Node的反向代理。

感谢这个家伙: https://www.tonyerwin.com/2014/09/redirecting-http-to-https-with-nodejs.html

如果安全,请求通过https,否则重定向到https

app.enable('trust proxy')
app.use((req, res, next) => {
    req.secure ? next() : res.redirect('https://' + req.headers.host + req.url)
})

这个答案需要更新以与Express 4.0一起工作。下面是我如何让单独的http服务器工作:

var express = require('express');
var http = require('http');
var https = require('https');

// Primary https app
var app = express()
var port = process.env.PORT || 3000;
app.set('env', 'development');
app.set('port', port);
var router = express.Router();
app.use('/', router);
// ... other routes here
var certOpts = {
    key: '/path/to/key.pem',
    cert: '/path/to/cert.pem'
};
var server = https.createServer(certOpts, app);
server.listen(port, function(){
    console.log('Express server listening to port '+port);
});


// Secondary http app
var httpApp = express();
var httpRouter = express.Router();
httpApp.use('*', httpRouter);
httpRouter.get('*', function(req, res){
    var host = req.get('Host');
    // replace the port in the host
    host = host.replace(/:\d+$/, ":"+app.get('port'));
    // determine the redirect destination
    var destination = ['https://', host, req.url].join('');
    return res.redirect(destination);
});
var httpServer = http.createServer(httpApp);
httpServer.listen(8080);

经过多年研究从http到https的完美重定向,我在这里找到了完美的解决方案。

const http = require("http");
const https = require("https");

const { parse } = require("url");
const next = require("next");
const fs = require("fs");

const ports = {
http: 3000,
https: 3001
}

const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();

const httpsOptions = {
key: fs.readFileSync("resources/certificates/localhost-key.pem"),
cert: fs.readFileSync("resources/certificates/localhost.pem")
};

// Automatic HTTPS connection/redirect with node.js/express
// source: https://stackoverflow.com/questions/7450940/automatic-https- 
connection-redirect-with-node-js-express
app.prepare().then(() => {

// Redirect from http port to https
http.createServer(function (req, res) {
    res.writeHead(301, { "Location": "https://" + req.headers['host'].replace(ports.http, ports.https) + req.url });
    console.log("http request, will go to >> ");
    console.log("https://" + req.headers['host'].replace(ports.http, ports.https) + req.url);
    res.end();
}).listen(ports.http, (err) => {
    if (err) throw err;
    console.log("ready - started server on url: http://localhost:" + ports.http);
});

https.createServer(httpsOptions, (req, res) => {
    const parsedUrl = parse(req.url, true);
    handle(req, res, parsedUrl);
}).listen(ports.https, (err) => {
    if (err) throw err;
    console.log("ready - started server on url: https://localhost:" + ports.https);
});
});