簡體   English   中英

如何使用反向代理處理 Express 應用程序中的重定向

[英]How to handle redirects in Express application with Reverse Proxy

我有兩個由 Nginx 提供服務的 Express 驅動的 NodeJS 應用程序。 一個應用程序是 RESTful API,由 Angular SPA 使用,另一個應用程序是管理門戶。 這是我試圖在這里實現的目標:

location / {
  # Serves Client Side Angular Application
}

location /api {
  # Serves RESTful Application
}

location /admin {
  # Serves Admin Portal
}

這是我對 nginx 的完整配置:

server { 
server_name localhost;
listen 80;
listen [::]:80;
index index.html;

location / { 
    expires -1; 
    add_header Pragma "no-cache"; 
    add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"; 
    root /var/www/example/client/dist;
    try_files $uri $uri/ /index.html =404; 
}

location /admin/ {
    proxy_pass http://127.0.0.1:3010/;
    proxy_http_version 1.1;
    rewrite /admin/(.*) /$1 break;
    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host/admin/;
    proxy_set_header X-NginX-Proxy true;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
} 

location /api { 
    proxy_pass http://127.0.0.1:3011;
    proxy_http_version 1.1;
    proxy_set_header X-Real-IP $remote_addr;
    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_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
}
} 

這兩個 NodeJS 應用程序都完美地使用並在其定義的端口上運行。

我的管理應用程序面臨的問題是,當我嘗試點擊http://example.com/admin它會將我重定向到http://example.com/login ,而它應該將我重定向到http://example.com/admin/login 我試圖通過向管理應用程序添加中間件來解決這個問題,例如:

app.use('*', function (req, res, next) {
 if(process.env.target === 'dev'){
   if(req.originalUrl.indexOf('/admin') > -1){
     res.redirect('/admin' + req.url);
   }
   next();
 }
});

但這不起作用。 我該如何處理這種情況? 無論如何nginx可以處理應用程序重定向? 如果沒有,我應該如何在不同環境(Dev、Staging、Prod 等)的應用程序中處理它? 我正在使用 nginx 1.4.6,節點 0.12.2 和 express 4.12.2。 如果我必須在我的應用程序中添加任何 3rd 方模塊,我沒有問題,但我更喜歡是否有針對我的問題的 nginx 解決方案。

謝謝。

您的 nginx 配置的問題是/admin路由的重寫:

rewrite /admin/(.*) /$1 break;

有了這條規則,您的管理門戶節點應用程序不知道它的路徑都托管在/admin根目錄下,因此如果您的應用程序執行重定向相對它認為是根目錄的內容,例如res.redirect('/login') ,它會將瀏覽器發送到localhost/login是有道理的。

另一種方法是刪除你的 nginx rewrite ,讓管理門戶知道這個/admin路徑。 這樣你就可以選擇重定向到一個相對路徑,像這樣: res.redirect('login')它告訴 express 考慮當前請求的路徑。 您可以使用express.Router使其更干凈,例如:

var adminRoutes = express.Router()
    .get('/', function(req, res) {
        if(!req.user) {
            // Will redirect to /admin/login
            res.redirect('login');
        } else {
            res.send('Hello');
        }
    })
    .get('/login', login);

// Tell express to host all routes above under a common /admin root
app.use('/admin', adminRoutes);

另一方面,如果您有更好的理由必須重寫 nginx,您始終可以為所有應用程序的重定向手動包含/admin根目錄。 您可以通過從proxy_set_header設置的自定義標頭中讀取它來臨時附加此掛載路徑。 例如:

app.use(function(req, res, next) {
    res.mountedAt = req.headers['X-Mounted-At'];
    next();
});

app.get('/', function(req, res) {
    res.redirect(path.join(res.mountedAt, '/login'));
});

我通過將 Andrew Lavers 的第一個解決方案與

        location /admin/ {
        proxy_pass          https://127.0.0.1:3010/admin/;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM