nginx处理跨域问题以及隐藏第三方地址

nginx处理跨域问题以及隐藏第三方地址

一、背景

场景,开发的系统,需要调用客户提供的ai审核接口,并且调用接口后,接口会返回后续操作的地址(这个地址是客户方的地址)。
最开始实现的方式是,前端请求接口拿到这个地址后,前端请求地址。但客户认为这个设计暴漏了ai审核相关的地址信息,要求隐藏这个地址,并且要求将这个地址内嵌到web页面。

涉及到信息,都用mock代替:
我们web的网页域名:
https://we.com
客户返回的地址:
http://3.3.2.2:33/ai/url

二、处理流程

实现方案:

在nginx配置拦截固定标识的请求,跳转到客户地址。后端返回替换后且带固定前缀标识的地址,前端在当前域名拼接上后端返回的地址,使用iframe对地址请求,并完成内嵌。
这样的好处在于避免了跨域问题,和隐藏了要跳转的真实地址。

实现中修改点:

后端改动:

后端调用客户接口拿到跳转地址,将跳转地址的ip和端口替换,并增加固定标识/turnToAiAudit

前端改动:

获取到后端返回的地址,拼上当前域名,使用iframe对地址请求,并完成内嵌

nginx配置:

1.配置拦截/turnToAiAudit,固定跳转到客户目标地址,配置信息为:

 location /turnToAiAudit/ {
              proxy_set_header    Host    $http_host;
              proxy_set_header    X-Real-IP       $remote_addr;
              proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
              client_max_body_size   10m;
              proxy_pass http://xx:xx/;
          }

2.注释跳转强制使用https请求:

#add_header Content-Security-Policy "upgrade-insecure-requests;connect-src *" always;

客户方改动:

1.提供的网页代码.css,.js等,访问路径都加上/turnToAiAudit前缀
2.注释跳转强制使用https请求:

#add_header Content-Security-Policy "upgrade-insecure-requests;connect-src *" always;

遇到的问题:
1.配置nginx代理后,客户提供的css等访问不到,显示的路径为:
https://we.com/客户提供的.css
2.配置nginx代理后,成功跳转到客户ip和端口,但客户网页中,还有部分是他们提供的ip和端口,查看后显示为https:客户的ip:端口。这个处理方式,客户在他们nginx配置【
注释跳转强制使用https请求】。

三、原理理解

大致理解:
前端代码在浏览器中运行,可以理解为浏览器通过域名和路径找到了,放到服务器上的前端代码文件,并完成解析和渲染最终显示了前端页面。
浏览器如何找到这个前端代码文件,就是通过域名,比如https://we.com/fornt/home,这个front/home就是文件存放的路径,至于互联网中有很多个服务器,要找到对应的服务,就是通过域名,比如:https://we.com

Deepseek:

你的理解基本正确,可以补充几个关键点:

域名解析:we.com 会通过 DNS 系统转换为服务器的 IP 地址(如 192.168.1.1),这才是服务器在互联网中的"门牌号"。
路径不一定是真实路径:像 /front/home 这类路径,实际可能是前端路由(如 React/Vue 的单页应用),服务器可能返回同一个 HTML 文件,由前端框架处理页面切换。
服务器配置:服务器(如 Nginx)会定义如何处理请求,比如:
/static/ 开头的请求返回静态文件(JS/CSS)
其他路径可能统一返回 index.html
文件可能被优化:前端代码通常会打包压缩(如 app.a3b4c5.js),文件名和路径可能与源码不同。
CDN 加速:像图片/CSS/JS 等静态资源,可能通过 CDN 分发到全球节点,而非直接来自 we.com 的服务器。
总结:域名找服务器,路径由服务器规则处理,最终返回前端资源,但路径和文件不一定一一对应。

Nginx 核心作用是「反向代理」,nginx可以理解为一个中转站,在浏览器和java服务中间的一个中转站。配置了拦截目录后,/turnToAiAudit,访问https://we.com/turnToAiAudit/**路径时,就会被拦截,它拦截请求后,而是将请求转发到目标服务(如 Java 服务),再将结果返回给浏览器,整个过程用户无感知。

nginx的拦截转发,也就解释了,遇到的问题:1.配置nginx代理后,客户提供的css等访问不到,显示的路径为:https://we.com/客户提供的.css。因为当前请求的地址是,https://we.com,客户返回的css则是根据当前路径访问的,因此就组装成了,https://we.com/客户提供的.css,而实际能范围的是:http://客户ip和端口/客户提供的.css,因此访问不到。

同一ip(都是80端口)可以绑定无数个名 配置简单 里面包含一个配置文档:配置文档.doc 看一遍 大部分人都会设置了。 内容如下: NGNIX配置文档 1.解压文件到相应文件夹下(我解压到D:/下) (这里是图片) 目录结构如上 2.在D:\nginx\目录下用记事本新建一个文本文档改名为 proxy.conf。 proxy.conf里面的内容格式如下: server { listen 80; server_name www.*****.com; location / { proxy_pass http://192.168.45.1:8045; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } (完整拷贝上面的内容server_name www.*****.com; 这里面的名即是来访名 proxy_pass http://192.168.45.1:8045; 这里面的名(http://192.168.45.1:8045)即是内部跳转的地址,将该内容拷贝多份实现不同来访名的跳转) 如下: 3.找到D:\nginx\conf下nginx.conf文件用记事本打开 在文段末尾大括号前加上 include proxy.conf;(就是加载刚刚新建的那个文件(注意路径)) 4.进入cmd 进入D盘: d: 进到nginx文件夹下:cd nginx 启动nginx.exe:start nginx Cmd窗口会闪一下 进程里面会多了个 浏览器里面输入:http://127.0.0.1 将出现: Nginx的欢迎界面。 注: nginx -s stop // 停止nginx nginx -s reload // 重新加载配置文件 nginx -s quit // 退出nginx nginx-1.3.9.zip(这个版本) (1分钟搞定只是夸张说法啦,给你增加信心的啦,真正的操作起来,因人而异,没搞定的耐心再试试,自己xp系统亲测成功,不喜欢的无拍砖哦,实在搞不定的加我qq852208555 一起研究下 谢谢!)
<think>好的,用户之前问的是关于多个不同名服务如何实现单点登录,我给出了三个方案和一些技术细节。现在用户追问“全局票证怎么传输”,感觉用户可能对之前的解释中关于票据传递的具体机制还不够清楚,尤其是在情况下如何安全传输全局票据(比如TGT或Token)。 首先,我需要确定用户所说的“全局票证”具体指什么。在CAS单点登录中,通常有TGT(Ticket Granting Ticket)作为全局票据,而ST(Service Ticket)是针对每个服务的。用户可能想知道TGT这类全局票据如何在不同的名之间传递,或者ST如何被不同名的服务验证。 用户可能对传输的具体技术细节有疑问,比如Cookie如何携带,或者前端如何在不同之间传递票据。可能之前的回答虽然提到了方案,但没有深入解释具体的传输机制,比如CORS、PostMessage、JSONP或者服务器端的重定向流程。 接下来,我需要分步骤解释传输的几种方法。首先,CAS的TGT是存储在中央认证中心的名下,比如.cas-center.com,这样所有子的服务都可以共享这个Cookie。但如果是完全不同名,比如app1.com和app2.net,这时候TGT的Cookie无法直接共享,需要其他方法。 可能的传输方式包括通过URL参数传递Service Ticket,或者使用OAuth2的授权码模式,通过前端重定向和中间页面传递Token。另外,可能需要使用隐藏的iframe或window.postMessage来实现通信。 还要考虑安全性,比如如何防止票据被截获,使用HTTPS,Token的加密签名,以及一次性票据的有效期等。同时,要提到现代浏览器中的SameSite Cookie策略对的影响,需要设置Secure和SameSite=None。 用户可能实际应用中遇到了单点登录的问题,比如在实现时遇到Cookie无法携带或者验证失败的情况,需要具体的解决步骤。因此,回答中需要包括具体的例子,比如CAS的流程步骤,代码示例,或者配置方法,让用户能够更好地理解如何实施。 另外,可能需要区分不同场景,比如传统Web应用、SPA单页应用、移动端等,不同的场景下传输票据的方式可能不同。例如,SPA可能需要使用OAuth2的隐式模式或PKCE,而传统Web应用则依赖服务端重定向和Session Cookie。 最后,需要检查是否有遗漏的关键点,比如CAS协议中的代理票据、网关模式中的统一名,或者使用JWT作为Token的自包含验证方式,减少对中央认证服务的依赖。这些都可能影响票据的传输方式。 总结下来,用户需要的是一个清晰、具体的票据传输机制的解释,包括技术实现、安全考虑和实际示例,以帮助他们理解并解决实际开发中的问题。</think>传输全局票证(如CAS的TGT票据或JWT令牌)的核心挑战在于**浏览器同源策略限制**。以下是具体实现方案与技术细节,用快递中转站模型来比喻: --- ### **一、基础原理:快递包裹如何区运输** 假设: - 中央认证中心 = 快递总部(`cas.com`) - 业务系统A = 北京分站(`app1.net`) - 业务系统B = 上海分站(`app2.org`) **运输流程**: ```mermaid graph TB 用户访问app1.net --> 检查包裹(本地Cookie) 检查包裹 -->|无包裹| 呼叫总部[重定向到cas.com/login?service=app1.net] 呼叫总部 --> 用户填写运单(输入账号密码) 用户填写运单 --> 获得总部盖章的**主运单**(TGT Cookie存在cas.com) 获得总部盖章的**主运单** --> 生成北京专用子运单(ST票据) 生成北京专用子运单 --> 派送包裹[重定向回app1.net?ticket=ST-123] ``` --- ### **二、传输三大核心技术** #### **1. 主票据(TGT)的携带 - 像国际快递的主运单** **实现方式**: ```http # CAS认证成功后设置Cookie HTTP/1.1 302 Found Location: https://app1.net/login?ticket=ST-123 Set-Cookie: TGT=ABCD-1234; Domain=.cas.com; Path=/; Secure; SameSite=None ``` **关键点**: - `Domain=.cas.com` 允许所有`*.cas.com`子共享(但无法完全不同的名) - 完全时(如`app1.net`与`app2.org`),需要**二次跳转验证** #### **2. 服务票据(ST)的验证 - 像区分站验证子运单** **验证流程**: ```python # app2.org 的验证代码示例 def validate_ticket(request): st = request.GET.get('ticket') # 向CAS总部发起验证请求(HTTP调用) response = requests.get( "https://cas.com/serviceValidate", params={'service': 'app2.org', 'ticket': st} ) # 解析XML响应获取用户信息 if response.status_code == 200: create_session(extract_user(response.xml)) ``` #### **3. 顶级传递 - 像国际物流中转** **场景**:用户已登录`app1.net`,要访问`app2.org` **实现步骤**: 1. 访问`app2.org`时检测无本地Session 2. 重定向到CAS中心: ```url https://cas.com/login?service=app2.org ``` 3. **自动携带CAS的TGT Cookie**(因浏览器已存) 4. CAS生成新的ST票据给`app2.org` --- ### **三、现代浏览器的特殊处理** #### **SameSite Cookie限制解决方案** ```javascript // 在CAS认证页面添加中转脚本 const token = getTokenFromURL(); // 使用隐藏的iframe传递到其他 const iframe = document.createElement('iframe'); iframe.src = `https://app2.org/token-receiver?token=${token}`; iframe.style.display = 'none'; document.body.appendChild(iframe); ``` #### **Safari智能防跟踪应对** ```nginx # Nginx配置添加CORS头 add_header 'Access-Control-Allow-Origin' 'https://cas.com'; add_header 'Access-Control-Allow-Credentials' 'true'; ``` --- ### **四、不同场景下的传输方式** #### **场景1:传统多页面应用** ```mermaid sequenceDiagram 用户->>app1.net: 访问资源 app1.net->>浏览器: 重定向到cas.com/login 用户->>cas.com: 提交登录表单 cas.com->>浏览器: 设置TGT Cookie + 重定向回app1.net?ticket=ST1 app1.net->>cas.com: 验证ST1 cas.com->>app1.net: 返回用户信息 用户->>app2.org: 访问其他服务 app2.org->>浏览器: 重定向到cas.com/login?service=app2.org 浏览器->>cas.com: 自动携带TGT Cookie cas.com->>app2.org: 生成ST2并重定向 ``` #### **场景2:单页应用(SPA)** ```javascript // 在CAS认证成功后 const popup = window.open('https://cas.com/login?service=app2.org'); popup.onload = () => { const token = popup.document.getElementById('token').value; // 使用postMessage传递 window.opener.postMessage({ type: 'sso_token', token }, '*'); }; ``` --- ### **五、安全加固措施** #### **票据加密示例(JWT方式)** ```python # CAS生成ST票据 import jwt st = jwt.encode( { 'user': 'john', 'exp': datetime.utcnow() + timedelta(seconds=30), 'service': 'app2.org' }, 'CAS_SECRET_KEY', algorithm='HS256' ) ``` #### **防御CSRF攻击** ```html <!-- 在重定向URL中添加随机state --> <a href="https://cas.com/login?service=app2.org&state=ABC123"> ``` --- ### **六、各方案对比表** | 传输方式 | 适用场景 | 安全性 | 实现复杂度 | 示例 | |-----------------------|---------------------|------|--------|-------------------------| | **Cookie顶级** | 同根名不同子 | 高 | 低 | `.cas.com`覆盖`a.cas.com` | | **URL参数传递ST票据** | 传统Web应用 | 中 | 中 | `app.net?ticket=ST-123` | | **postMessage通信** | 现代SPA应用 | 高 | 高 | 窗口消息传递 | | **服务端Session共享** | 内部系统统一缓存 | 高 | 高 | Redis集群存储Session | | **OAuth2 Token中继** | 开放平台第三方接入 | 高 | 高 | JWT携带用户信息 | 如果需要具体到某个框架(比如Spring Security CAS Client或Auth0)的配置代码,可以告诉我你的技术栈 😄
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值