HOWTO · Node.js

NodeJS 中的 HTTP 代理伺服器

本教程演示如何在 NodeJS 中建立 http 代理伺服器。

本頁內容

代理伺服器會接收用戶端的請求,再轉送至另一台伺服器。本指南會建立 Express 路由,將 /user_info 下的請求轉送至上游服務,接著示範檢查標頭是否存在的中介軟體。這項示範用來說明請求流程,並非正式環境可用的身分驗證。

在 Node.js 中建立 HTTP 代理

請先安裝 Node.js 和 npm,再使用 npm init -y 建立專案。接著執行 npm install express http-proxy-middleware,安裝 Express 和代理中介軟體套件。該套件會匯出下方使用的 createProxyMiddleware 工廠函式。官方文件介紹了此工廠函式,以及 target、origin 和路徑改寫選項。npm 版本不同,產生的套件清單也可能不同,因此請使用安裝指令,而不要照抄固定的套件清單。

設定代理路由並改寫路徑

在 index.js 中使用 CommonJS require() 匯入方式。授權中介軟體會掛載在 /user_info,但代理中介軟體是在未掛載路徑的 Express 處理常式中呼叫;該處理常式會先確認請求路徑是否以 /user_info/ 開頭。如此一來,代理就能收到完整路徑。pathRewrite 規則會移除這個前綴:/user_info/data/v1/user/example 會在轉送至上游時變成 /data/v1/user/example。請將 target 設為由你管理的上游來源站;若上游預期收到自己的主機名稱,則使用 changeOrigin。

以下程式碼行依序串接後就是 index.js。標頭中介軟體會先於代理執行,伺服器則監聽連接埠 8080:

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
app.use('/user_info', (req, res, next) => {
if (!req.headers.authorization) return res.sendStatus(403);
next();
});
const proxy = createProxyMiddleware({
target: 'https://api.example.com',
changeOrigin: true,
pathRewrite: { '^/user_info': '' }
});
app.use((req, res, next) => {
if (!req.path.startsWith('/user_info/')) return next();
proxy(req, res, next);
});
app.listen(8080, () => console.log('Proxy listening on port 8080'));

若要在不依賴可連線的上游服務時示範路徑與標頭判斷,請執行以下僅使用內建功能的範例。範例程式碼與輸出中的標籤維持英文,方便對照原始內容:

本節中的程式碼以及顯示的標籤或輸出仍為英文。

const rewrite = path => path.replace(/^\/user_info/, '');
const authorizationGate = headers => Boolean(headers.authorization);

const incomingPath = '/user_info/data/v1/user/example';
console.log(`Upstream path: ${rewrite(incomingPath)}`);
console.log(`Request without Authorization: ${authorizationGate({}) ? 'allowed' : '403 Forbidden'}`);
console.log(`Request with Authorization: ${authorizationGate({ authorization: 'present' }) ? 'allowed' : '403 Forbidden'}`);
Upstream path: /data/v1/user/example
Request without Authorization: 403 Forbidden
Request with Authorization: allowed

這個簡短範例模擬預期的判斷流程。Express 應用程式本身則需要安裝上述兩個套件,並連接上游服務。

執行並測試代理

請將 https://api.example.com 替換為接受改寫後路徑的上游來源站,接著使用 node index.js 啟動應用程式。執行 curl http://localhost:8080/user_info/data/v1/user/example 傳送請求。實際回應取決於上游服務,因此請檢查回應狀態和本文內容,不要預期會收到固定回應。若收到找不到資源的回應,可能是上游沒有提供 /data/v1/user/example;請確認上游預期的路徑。

新增 Authorization 中介軟體

第一個 /user_info 中介軟體只會檢查 Authorization 是否存在,並呼叫 next(),讓通過檢查的請求繼續交給代理中介軟體。Express 會依照中介軟體的註冊順序執行,因此這項檢查必須先註冊。任何非空標頭都會通過;程式碼不會驗證身分、憑證或權限。這些判斷應交由真正的身分驗證系統處理,並避免記錄機密值。

測試有無 Authorization 的請求

啟動伺服器後,執行 curl -i http://localhost:8080/user_info/data/v1/user/example;未帶標頭時,示範用的中介軟體會在轉送前回傳 HTTP 403。接著使用測試標頭傳送請求,例如 curl -i -H 'Authorization: test-value' http://localhost:8080/user_info/data/v1/user/example。此請求會繼續送往上游,回應內容取決於上游的路由和存取規則。請勿在 shell 歷史紀錄或範例中放入真實憑證。如果未帶標頭的請求仍抵達上游,請確認標頭檢查中介軟體註冊在代理呼叫之前。代理是由另一個未掛載路徑的處理常式呼叫,並會檢查 /user_info/ 前綴;它並未掛載在 /user_info 上。