请教大佬们一个反向代理问题

2023-08-25 10:02:35 +08:00
 seeyourface

前提: A 应用中通过微前端的方式嵌入了一个 B 应用,A 应用运行在 nginx 监听的 443 端口,防火墙开放 443 端口。 B 应用运行在 8081 端口并且防火墙不开放该端口,B 应用拦截器中做了一个简单的认证,只要请求 B 应用的接口中的请求头含有 X-User-Name 头部并且值不为空就能请求成功,否则认证失败。 现在在 nginx 中将/source (表示 B 应用接口的请求)开头的请求都代理到了 8081 ,且同时自动添加请求头部 X-User-Name ,本意是使 A 应用能正常访问 B 应用 但是浏览器访问 Protocol://ip:6433/source 时 B 应用会自动跳转到自己的/home 地址,然后请求主页相关接口并且都带上了头部,导致可以从浏览器访问 B 应用。 在不修改代码的情况下,能不能只通过修改 nginx 配置实现浏览器无法访问 B 应用,A 应用通过嵌入方式可以正常访问 B 应用;

nginx 反向代理配置:

location ^~ /source { proxy_set_header X-User-Name '1'; proxy_pass https://127.0.0.1:8081; }

2150 次点击
所在节点    NGINX
14 条回复
luhuisicnu
2023-08-25 10:14:07 +08:00
简单,浏览器无法主动添加这个 X-User-Name header 。所以 nginx 配置里面不加这个 header ,让 A 应用嵌入的 B 应用的超链接,js 添加这个 header ,就行了
dier
2023-08-25 10:19:33 +08:00
ChatGPT 建议加一个"add_header X-Frame-Options "SAMEORIGIN";" 来限制非同源来访问这个页面。你试试

```
location ^~ /source {
proxy_set_header X-User-Name '1';
proxy_pass https://127.0.0.1:8081;
add_header X-Frame-Options "SAMEORIGIN"; # 添加 X-Frame-Options 防止页面被嵌套
}

```
seeyourface
2023-08-25 10:25:30 +08:00
@luhuisicnu 我懂前端,前端开发说微前端的嵌入方式他只是引入了一个 B 应用的地址,具体请求的接口他都不知道也不能往请求头里面加 header ,大佬你这个 js 添加 header 是指什么
seeyourface
2023-08-25 10:26:01 +08:00
@seeyourface 说错了,我不懂。。。
seeyourface
2023-08-25 10:28:39 +08:00
@dier 试了一下,还是不行
dier
2023-08-25 10:37:56 +08:00
@seeyourface #5 试试这个呢 "add_header Content-Security-Policy "frame-ancestors 'self'";"
zhongerbing
2023-08-25 10:41:34 +08:00
@seeyourface #3 微前端一般都有通信方式,直接使用通信的方式来让 b 应用添加。如果单独打开也拿不到 a 通信过来的数据,应该就可以实现你的需求
cdswyda
2023-08-25 10:54:40 +08:00
allow 127.0.0.1; # 只让 nginx 代理访问
deny all; # 禁止其他所有 IP 地址访问
JohnSwit
2023-08-25 11:04:45 +08:00
要实现这个需求,其实就是确保访问 B 的时候,根据条件带上 X-User-Name Header ,你这样设置跳转肯定会自动带上的。

你的 B 应用是内嵌到 A 应用内部,本意是使 A 应用能正常访问 B 应用,那么从 A 应用请求到 B 应用,应该是可以带上 A 应用的标识吧?

基于你的条件,location ^~ /source { proxy_set_header X-User-Name '1'; proxy_pass https://127.0.0.1:8081; }

你可以添加多一个 IF 条件去判断,包含 A 应用的特定标识再去添加头:
if ($http_referer ~* "yourAAppIdentifierHere") {
proxy_set_header X-User-Name '1';
}
dallaslu
2023-08-25 11:10:13 +08:00
这问题与反代、AB 应用关系都不大吧,问题的核心是,如何让微前端可用,而浏览器直接访问不可用。

重点是你这个「微前端」嵌入是怎么实现的。(啥叫微前端嵌入啊?)

按描述来说,既不关心接口,又不能修改请求头,所以……是 iframe 吗?

Nginx 可以尝试检查 referer ,或者在页面写入一段 JS ,用来检查是否处于「被嵌入」状态,否则跳转页面。
seeyourface
2023-08-25 11:14:58 +08:00
@dallaslu 前端只给我发了一这行代码,他说嵌入 B 应用只写了一行:<micro-app name="B" url={micro_url} baseroute="/preparation/B" keep-alive />
seeyourface
2023-08-25 11:16:18 +08:00
@cdswyda 这样嵌入的应用也访问不了
dallaslu
2023-08-25 11:22:55 +08:00
根据文档 <https://zeroing.jd.com/micro-app/docs.html#/zh-cn/env>,可以检测到是否为微前端。插入脚本检测环境即可。

```nginx
server {
listen 80;
server_name your_domain.com;

location /source {
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

sub_filter '<head>' '<head><script>if(!window.__MICRO_APP_ENVIRONMENT__) alert('You bad bad')</script>';
sub_filter_once on;
}
}
```
seeyourface
2023-08-25 13:49:33 +08:00
@dallaslu 确实可以从请求头的 Referer 字段入手,微前端访问和浏览器访问这个字段的内容不同,多谢大佬

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/968180

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX