自动HTTPS连接/与node.js / express重定向

我一直在尝试通过正在处理的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开发,所以如果这很明显,请原谅我的无知。

逆天宝儿米亚2020/03/24 14:10:00

您可以实例化2个Node.js服务器-一个用于HTTP和HTTPS

您还可以定义两个服务器都将执行的设置功能,因此您不必编写太多重复的代码。

这是我的方法:(使用restify.js,但也应该适用于express.js或节点本身)

http://qugstart.com/blog/node-js/node-js-restify-server-with-both-http-and-https/

西里神奇2020/03/24 14:10:00

这为我工作:

app.use(function(req,res,next) {
    if(req.headers["x-forwarded-proto"] == "http") {
        res.redirect("https://[your url goes here]" + req.url, next);
    } else {
        return next();
    } 
});
猪猪L2020/03/24 14:10:00

这里的大多数答案都建议使用req.headers.host标头。

Host标头是HTTP 1.1所必需的,但实际上是可选的,因为标头可能实际上不是由HTTP客户端发送的,并且node / express将接受此请求。

您可能会问:哪个HTTP客户端(例如:浏览器)可以发送缺少该标头的请求?HTTP协议非常简单。您可以用几行代码编写HTTP请求,而不发送主机头,并且,如果每次收到格式错误的请求时,都会引发异常,并根据如何处理此类异常而使服务器宕机。

因此,请始终验证所有输入这不是偏执狂,我收到的请求缺少服务中的主机头。

另外,切勿将URL视为string使用节点url模块来修改字符串的特定部分。将URL视为字符串可以通过多种方式加以利用。不要这样

神无2020/03/24 14:10:00

我在使用express时发现req.protocol有效(未经测试,但我怀疑它有效)。在Express 3.4.3中使用当前节点0.10.22

app.use(function(req,res,next) {
  if (!/https/.test(req.protocol)){
     res.redirect("https://" + req.headers.host + req.url);
  } else {
     return next();
  } 
});
DavaidTony宝儿2020/03/24 14:09:59

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

某些人通过让Node的HTTPS服务器(也可以与Express.js一起使用)侦听443(或其他端口),并且使小型http服务器绑定到80并将用户重定向到安全端口,从而解决了此问题。

如果绝对必须能够在单个端口上处理两个协议,则需要在该端口上放置nginx,lighttpd,apache或其他Web服务器,并充当Node的反向代理。

小宇宙2020/03/24 14:09:59

使用Nginx,您可以利用“ x-forwarded-proto”标头:

function ensureSec(req, res, next){
    if (req.headers["x-forwarded-proto"] === "https"){
       return next();
    }
    res.redirect("https://" + req.headers.host + req.url);  
}