在Express/Node中强制通过https请求

rob*_*cks 6 node.js express

我有一个在端口3100上运行的Express.js(v 2.5.8)(节点v0.6.12)服务器.它由Nginx前端,它将http和https请求代理到端口3100.

我想通过https强制某些网址.这是一个例子(app是我的Express服务器):

app.get('/applyNow', ensureSec, secure.showApplication );
Run Code Online (Sandbox Code Playgroud)

ensureSec是我试图用来检查连接是否超过ssl的函数:

function ensureSec(req, res, next) {
    if (req.session.ssl == true) { 
        return next(); 
    } else {
        req.session.ssl = true;
        res.redirect('https://' + url.parse(req.headers.referer).host +
        url.parse(req.url).pathname);
    }
}
Run Code Online (Sandbox Code Playgroud)

重定向工作,但节点(超时后)抛出一个错误,说"不能GET/applyNow

重定向到ssl的正确方法是什么?

Lin*_*iel 7

据我所知,您正在使用nginx协商SSL并将http和https请求代理到您的Express应用程序.如果可能的话,我会选择在nginx中解决这个问题,但如果nginx无法知道哪些路径应该受到保护(即只能通过https获得),或者你想在快递应用中出于其他原因这样做,这里有一些信息:

您应该X-Forwarded-Proto从nginx 获取,https仅在原始协议为https时设置.以下是在nginx中执行此操作的方法:

proxy_set_header X-Forwarded-Proto https;
Run Code Online (Sandbox Code Playgroud)

我也会转发Host标题:

proxy_set_header Host $http_host;
Run Code Online (Sandbox Code Playgroud)

在您的快速应用程序中,检查它,或重定向到标题和请求的路径中的主机(明确解析,req.path所以你不必):

function ensureSec(req, res, next) {
    if (req.headers['x-forwarded-proto'] == 'https') { 
        return next(); 
    } else {
        res.redirect('https://' + req.headers.host + req.path);
    }
}
Run Code Online (Sandbox Code Playgroud)