Nginx反向代理+ ExpressJS + Angular + SSL配置问题

时间:2018-12-16 23:28:06

标签: node.js angular express ssl nginx

我是新手,我有一些我无法通过Google回答的问题。

如果我做对了- nginx 是我的网络服务器-已完成对服务器的请求,并且 nginx 服务于我的客户端(Angular),但我也可以使用我的Express应用程序与res.sendFile()一起使用? 如果我使用反向代理设置nginx,它可以作为客户端和后端之间的实例吗?因此,他们不是直接通过nginx进行通信,而是这样做,我必须proxy_pass我的Express应用程序?

我的nginx网站可用的配置:

# Default server configuration
#
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name blank-agency.org www.blank-agency.org;
    return 301 https://$server_name$request_uri;
} 


server {    
    # SSL configuration
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

    ssl on;

ssl_certificate /etc/letsencrypt/live/blank-agency.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blank-agency.org/privkey.pem;

server_name blank-agency.org www.blank-agency.org;  
root /var/www/webserver/public/website;



    location ~ /.well-known {
            allow all;
    }


location / {

    proxy_pass https://localhost:3000;
             proxy_http_version 1.1;
             proxy_set_header Upgrade $http_upgrade;
             proxy_set_header Connection 'upgrade';
             proxy_set_header Host $host;
             proxy_cache_bypass $http_upgrade;

}

您可以看到我的目录结构是:

/ var / www / webserver->这是我的快递app.js

/ var / www / webserver / public / website->这是我的角度dist文件

如果我使用nginx作为反向代理,我的客户端不再可用(bad gateway 502),那么我想现在必须通过Express应用程序为其提供服务吗?

现在我的app.js

// require section

var express = require('express'),
    mysql = require('mysql'),
    bodyParser = require('body-parser'),
    cors = require('cors'),
    path = require('path'),
    app = express();

// middlewares bodyParser + cors
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());



var connection = mysql.createConnection({
    host: '127.0.0.1',
    user: 'root',
    password: 'whatever',
    database: 'whateverDB'
});

connection.connect();


app.use( express.static(__dirname + '/public/website'));

app.get('/', function(req, res){
    res.sendFile(path.join(__dirname + '/public/website/index.html'));
});

app.route('/customers').get((req, res) => {
   connection.query('SELECT * FROM customers', function (err, rows) {
      const results = JSON.stringify(rows);
      console.log(req.param("term"));
      res.send(results);
   })

})



// app listen port

app.listen(3000, function () {
    console.log('Example app listening on port 3000!');
});

再次一切正常,但是为什么我可以通过http://blank-agency.org:3000访问我的应用程序?首先应该将HTTP请求重定向到HTTPS吗?与https://blank-agency/customers相同->我在URL上公开的数据似乎是一个安全问题,哈哈

我知道它是在端口3000上提供的,因为我是通过侦听端口3000的Express应用程序发送它的,但还应该如何提供它呢?因为具有反向代理设置的Nginx会产生502错误,如前所述,并且我已经通过Linux上的80 & 443在防火墙上打开了端口iptables

netstat -tlpn

在端口80和443上显示nginx

systemctl status nginx

nginx -t

一切都很好。

我想我对这里使用的概念有很深的误解,或者其他不对的地方。 让我知道您是否需要更多信息。

预先感谢:)

2 个答案:

答案 0 :(得分:0)

第一部分:

app.listen(3000, 'localhost', function () {
  console.log('Example app listening on port 3000!');
});

这将阻止访问http://blank-agency.org:3000,因为现在nodeexpressjs不会侦听所有地址,而只会侦听localhost。 (假设nginx和node / expressjs都在同一服务器上运行)。

第二部分:

location /customers {
    proxy_pass https://localhost:3000/customers;
         proxy_http_version 1.1;
         proxy_set_header Upgrade $http_upgrade;
         proxy_set_header Connection 'upgrade';
         proxy_set_header Host $host;
         proxy_cache_bypass $http_upgrade;
}

这只会将https://blank-agency.org/customers的代理反向转换为node/expressjs。为了减轻配置负担,最好在公用路径下收集所有expressjs URL,例如:/api/customers/api/products/api/auth等。这样,您将必须反向代理从/api仅配置一次。

如果您需要身份验证,则angular应用程序和node/expressjs应该实现该身份验证,那么您将拥有更多的反向代理路径,例如location /api/auth { ... }等。但这部分是特定于应用程序的, nginx会将HTTP请求移交给node/expressjs,并将响应移交给客户端。从nginx的角度来看,它应该是透明的。

答案 1 :(得分:0)

为将来参考,您绝对可以同时通过Nginx和express-static提供文件。

我在server.js中拥有此文件,当在没有Nginx的情况下本地运行时,该文件将提供./public/中的所有文件。

app.use('/assets', express.static(path.join(__dirname, 'public')));
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));

然后在Nginx配置中,我将其提供给同一目录。在生产环境中,它将由Nginx完全处理,并且永远不会在/assets上使用Express应用程序。

location /assets/ {
    alias /home/app/public/;
    sendfile on;
    sendfile_max_chunk 5m;
    tcp_nopush on;
  }

由于Prerender.io配置的原因,我的代理通过比较复杂,但是您需要遵循这些原则。这会将 /assets/以外的任何内容发送到您的Express服务器。

location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    proxy_redirect off;
    proxy_pass http://127.0.0.1:5000;
}