前提: 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; }
1
luhuisicnu 2023-08-25 10:14:07 +08:00
简单,浏览器无法主动添加这个 X-User-Name header 。所以 nginx 配置里面不加这个 header ,让 A 应用嵌入的 B 应用的超链接,js 添加这个 header ,就行了
|
2
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 防止页面被嵌套 } ``` |
3
seeyourface OP @luhuisicnu 我懂前端,前端开发说微前端的嵌入方式他只是引入了一个 B 应用的地址,具体请求的接口他都不知道也不能往请求头里面加 header ,大佬你这个 js 添加 header 是指什么
|
4
seeyourface OP @seeyourface 说错了,我不懂。。。
|
5
seeyourface OP @dier 试了一下,还是不行
|
6
dier 2023-08-25 10:37:56 +08:00
@seeyourface #5 试试这个呢 "add_header Content-Security-Policy "frame-ancestors 'self'";"
|
7
zhongerbing 2023-08-25 10:41:34 +08:00
@seeyourface #3 微前端一般都有通信方式,直接使用通信的方式来让 b 应用添加。如果单独打开也拿不到 a 通信过来的数据,应该就可以实现你的需求
|
8
cdswyda 2023-08-25 10:54:40 +08:00
allow 127.0.0.1; # 只让 nginx 代理访问
deny all; # 禁止其他所有 IP 地址访问 |
9
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'; } |
10
dallaslu 2023-08-25 11:10:13 +08:00
这问题与反代、AB 应用关系都不大吧,问题的核心是,如何让微前端可用,而浏览器直接访问不可用。
重点是你这个「微前端」嵌入是怎么实现的。(啥叫微前端嵌入啊?) 按描述来说,既不关心接口,又不能修改请求头,所以……是 iframe 吗? Nginx 可以尝试检查 referer ,或者在页面写入一段 JS ,用来检查是否处于「被嵌入」状态,否则跳转页面。 |
11
seeyourface OP @dallaslu 前端只给我发了一这行代码,他说嵌入 B 应用只写了一行:<micro-app name="B" url={micro_url} baseroute="/preparation/B" keep-alive />
|
12
seeyourface OP @cdswyda 这样嵌入的应用也访问不了
|
13
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; } } ``` |
14
seeyourface OP @dallaslu 确实可以从请求头的 Referer 字段入手,微前端访问和浏览器访问这个字段的内容不同,多谢大佬
|