我有一个在端口3100上运行的Express.js(v 2.5.8)(节点v0.6.12)服务器。它由Nginx前端,它将http和https请求代理到端口3100.
我想通过https强制某些网址。这是一个例子(app是我的Express服务器):
app.get('/applyNow', ensureSec, secure.showApplication );
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);
}
}
重定向有效,但节点(超时后)会抛出错误,说“无法获取/应用现在
重定向到ssl的正确方法是什么?
答案 0 :(得分:6)
据我所知,您正在使用nginx协商SSL并将http和https请求代理到您的Express应用程序。如果可能的话,我会选择在nginx中解决这个问题,但如果nginx无法知道哪些路径应该受到保护(即只能通过https获得),或者你想在快递应用中出于其他原因这样做,这里有一些信息:
您应该从nginx获取X-Forwarded-Proto
,仅在原始协议为https时设置为https
。以下是在nginx中执行此操作的方法:
proxy_set_header X-Forwarded-Proto https;
我还会转发Host
标题:
proxy_set_header Host $http_host;
在您的快递应用中,检查一下,或者在标题和请求的路径中重定向到主机(快递解析到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);
}
}
答案 1 :(得分:0)
您需要2个不同的快速app
对象才能执行此操作。快速服务器的每个实例一次只能侦听一个协议。这可以都在一个node.js进程中,但是您需要2个不同配置的快速服务器app
实例,一个用于http,另一个用于https。请参阅我的答案以获取示例:
How to force SSL / https in Express.js
另请参阅:Automatic HTTPS connection/redirect with node.js/express?
另请注意,您不应指定req.session.ssl
。将其设置为true并不会神奇地使客户端与TLS而不是明文HTTP连接。这是一个只读属性。分配它没有效果。
您还应注意,您无法在单个端口上同时运行http和https。这就是为什么http使用80而https使用443。
当您收到Cannot GET /applyNow
错误时,这意味着您的快速路由从未与请求路径匹配,因此您的ensureSec
中间件从未被调用过。
答案 2 :(得分:0)
您可以在nginx服务器上配置ssl端口,并像其他请求一样代理对node.js的请求。
http://nginx.org/en/docs/http/configuring_https_servers.html
无需更改node.js应用。只需使用您的证书和对node.js app的代理请求在nginx上配置443端口。
答案 3 :(得分:0)
要添加Peter Lyons所说的内容,请明确要求您在端口上只运行一台服务器。如果您尝试在一个端口上运行两个http服务器,它将抛出EADDRINUSE错误。
答案 4 :(得分:0)
如下所述:http://elias.kg/post/14971446990/force-ssl-with-express-js-on-heroku-nginx,使用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);
});
答案 5 :(得分:0)
当您在前端使用Nginx时,实现此目的的最简洁和最简单的方法是将Nginx中的http URL转发(重写)为HTTPS,而不是尝试在Express中重定向。这可以按如下方式完成:
server {
listen 12.34.56.78:80;
server_name yourserver.com;
location / {
rewrite ^ https://$server_name$request_uri permanent;
}
}
你可以用这一行重写:
rewrite ^ https://ducklington.org$request_uri permanent;
只需设置您的位置即可与您转发到https所需的路线或规则相匹配。
答案 6 :(得分:0)
app.enable(' trust proxy');
"在Varnish或Nginx等反向代理后面使用Express是微不足道的,但它确实需要配置。通过启用"信任代理"通过app.enable设置('信任代理'),Express会知道它位于代理后面,并且X-Forwarded- *标题字段可能是可信的,否则可能很容易。欺骗"