如何实现App2仅对App1认证用户开放 禁止用户直接访问App2
落地方案(无需修改App2任何代码)
核心思路:不要在前端/iframe层做拦截,所有访问控制下沉到你完全可控的反向代理/网络层,从根上杜绝App2被直接访问的可能。所有依赖HTTP头(Referer、X-Frame-Options等)的前端拦截方案都防不住刻意绕过的用户,只能防君子。
方案1:反向代理+短时效令牌(最优,安全性最高)
这个方案完全不暴露App2的公网访问入口,用户就算拿到路径也没有任何直接访问的可能:
- 第一步:网络层封禁App2的公网直连权限,仅允许内部反向代理(Nginx、API网关均可)访问App2的服务端口,公网用户根本无法直接触达App2源站。
- 第二步:App1完成用户登录认证后,生成一个有效期10秒以内、绑定用户IP、带服务端签名的一次性访问令牌,签名密钥只有App1和反向代理持有,无法伪造。
- 第三步:App1侧不管是用iframe嵌入还是页面跳转,给用户的App2访问地址都是走统一代理域名的路径,比如
https://你的业务域名/app2-proxy?token=签名生成的临时令牌,全程不暴露App2的真实源地址。 - 第四步:反向代理收到App2路径的请求时做两层校验:
- 首次访问带token参数的请求,先把token转发给App1的内部校验接口验证合法性,验证通过就给用户种下HttpOnly、Secure、SameSite严格模式的认证Cookie,然后重写URL去掉参数避免token泄露
- 后续所有App2路径的请求,直接校验认证Cookie是否合法,校验不通过直接返回403,校验通过才把请求内部转发给App2源站
极简Nginx参考配置:
server { listen 443 ssl; server_name 你的业务域名; # App1正常路由 location / { proxy_pass http://app1内网地址:服务端口; } # App2公网唯一访问入口 location /app2/ { # 处理首次带临时token的访问 if ($arg_token) { # 转发给App1内部接口校验token合法性 auth_request /verify_token; # 校验通过种认证Cookie add_header Set-Cookie "app2_valid=1;Path=/app2;HttpOnly;Secure;SameSite=Strict" always; # 重写URL去掉token参数 rewrite ^/app2/(.*)$ /app2/$1 permanent; } # 无合法Cookie直接拦截 if ($cookie_app2_valid != "1") { return 403; } # 校验通过才转发到内网App2源站 proxy_pass http://app2内网地址:服务端口/; } # 内部token校验接口,不对外暴露 location = /verify_token { internal; proxy_pass http://app1内网地址:服务端口/内部/verify-app2-token; } }
方案2:同域Cookie共享(轻量快速落地)
如果不想做临时令牌逻辑,可以用更简单的同域方案,同样不需要改App2代码:
- 同样先封禁App2的公网直连入口,所有App2请求走统一反向代理
- 把App1和App2挂在同一个根域名下,比如App1为
https://你的域名/,App2代理路径为https://你的域名/app2/ - App1完成登录后,种下根域生效的HttpOnly登录态Cookie
- 反向代理收到
/app2/路径的请求时,直接把Cookie转发给App1的认证接口校验登录态,合法就放行,不合法直接返回403
不推荐的方案说明
网上很多提到的iframe拦截方案都不具备落地安全性:
X-Frame-Options、CSP的frame-ancestors规则只能控制页面是否允许被iframe嵌入,完全拦不住用户直接在地址栏输入URL访问- Referer校验容易被篡改,且部分浏览器、隐私插件会默认不发送Referer,既容易误杀正常用户,也能被轻松绕过
- 所有在App2前端JS里写的判断父窗口逻辑,都需要修改App2代码,不符合你的约束,而且用户禁用JS就能直接绕过。
内容的提问来源于stack exchange,提问作者asanoop24
相关产品推荐
相关产品推荐

