# --------------------------------------------------------------------------- # upstream board_app(默认 127.0.0.1:3000)后端可以是以下任一实现,无需改本 conf: # - Node:npm run start(Express,见 src/app.ts + src/routes/boardRouter.ts) # - ASP.NET:Kestrel 监听 3000(见 aspnet/BoardApp,PathBase=/board) # 二者须满足的 HTTP 契约(供 auth_request 与浏览器同源 Cookie): # - GET /board/check/ 已登录 → 200;未登录 → 401(纯文本即可) # - Session Cookie 名 board.sid,Path=/,与 80 入口同主机以便 nginx 子请求带 Cookie # - /board/login、POST /board/api/login、/board/static/… 等由应用自身处理 # 配置目录:两套程序均读同一套 config/*.json(或通过 BOARD_CONFIG_DIR 指向同一目录)。 # --------------------------------------------------------------------------- # 访问模型(80 端口统一入口) # 1) 任意 URL 若匹配 /board/… → 直接反代到 Board(本机 board_app),不经过 auth_request, # 避免登录页、/api/login、/board/check/ 等与鉴权子请求死循环。 # 2) 其余所有路径 → 先 auth_request 调用内部 /internal/board_check(实质请求 Board 的 # GET /board/check/ 且透传 Cookie)。子请求返回 2xx 视为已登录,再 proxy_pass 到 DataEase。 # 子请求 401/403 → error_page 跳转到 /board/login?next=原 URI。 # 3) 注意:nginx 的「rewrite 到 8100」在这里通过 proxy_pass 实现(HTTP 反代),不是 rewrite 指令。 # --------------------------------------------------------------------------- upstream board_app { server 127.0.0.1:3000; } upstream dataease_upstream { server 127.0.0.1:8100; } server { listen 80; server_name 192.168.0.235; # 建议明确写出 IP 或域名 # 0) /board 无尾斜杠时,^~ /board/ 不会匹配,会误入 location / 被反代到 DataEase,必须显式纠正 location = /board { return 302 $scheme://$http_host/board/; } # 1) 门户应用自身的路径(优先级最高) # 确保 /board/ 及其子路径(登录页、API、静态资源)绝不走鉴权,否则会死循环 location ^~ /board/ { proxy_pass http://board_app; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # 2) 内部鉴权接口(仅由 auth_request 发起,外部无法直接访问) location = /internal/board_check { internal; proxy_pass http://board_app/board/check/; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header Host $host; proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 必须透传 Cookie,否则 Board 无法根据 session 判断已登录 proxy_set_header Cookie $http_cookie; } # 3) 核心控制:除 /board、/board/… 以外的所有请求 — 先鉴权,再反代 DataEase:8100 location / { auth_request /internal/board_check; # 鉴权子请求失败:跳转门户登录页(带 next 回跳) error_page 401 = @board_need_login; error_page 403 = @board_need_login; # 已登录:反代到 DataEase(等价于「非 board 流量进 8100」) proxy_pass http://dataease_upstream; # --- 关键修改:拦截 DataEase 自身的登录重定向 --- # 如果 DataEase 试图把用户甩到它自己的 /login,Nginx 强制拦截并改写 proxy_intercept_errors on; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 防止 DataEase 返回的 Location Header 暴露 8100 端口 proxy_redirect http://127.0.0.1:8100/ /; } # 4) 统一登录跳转逻辑 location @board_need_login { # $request_uri 包含了原始请求路径,登录后可跳回 return 302 $scheme://$http_host/board/login?next=$request_uri; } }