前言
ios14 默认关闭应用的 「允许跨站跟踪」的权限
微信浏览器没有提供 safari 和 chrome 等主流浏览器提供用户操作关闭「阻止跨网站跟踪」的功能
1、什么是跨域?
1.1 为什么会有跨域?
其实是出于浏览器的同源策略限制
- 出于浏览器的同源策略 / SOP(Same origin policy)限制
- 同源策略是一种约定,它是浏览器最核心也最基本的安全功能
- Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现
如果缺少了同源策略,浏览器很容易受到 XSS、CSRF 等攻击
1.2 什么是跨域?
源:协议、域名、端口
同源就是两个页面具有相同的 协议 (protocol)、主机 (host) 和端口号 (port)
- 当一个请求 url 的协议、域名、端口三者之间任意一个与当前页面 url 不同即为跨域
例如下表的 A 调用 B:
| A URL | BURL | 是否跨域 | 原因 |
|---|---|---|---|
| https://login.taobao.com/index.html | https://login.taobao.com/home.php | 否 | 协议、域名、端口号一致 |
| http://login.taobao.com/index.html | https://login.taobao.com/home.php | 是 | 协议不同 |
| https://cn.aliyun.com | https://login.taobao.com | 是 | 域名不同 |
| http://login.taobao.com:8080 | http://login.taobao.com:8081 | 是 | 端口号不同 |
2、解决跨域的几种方式
- 通过 jsonp 跨域
- document.domain + iframe 跨域
- location.hash + iframe
- window.name + iframe 跨域
- postMessage 跨域
- 跨域资源共享(CORS)
- nginx 代理跨域
- nodejs 中间件代理跨
-
3、业务遇到的跨域问题
3.1 问题背景
ios14 默认关闭应用的 「允许跨站跟踪」的权限
- 而且微信浏览器没有提供 safari 和 chrome 等主流浏览器提供用户操作关闭「阻止跨网站跟踪」的功能。导致 ios14 的用户使用微信浏览器无法登录我们业务
3.2 业务此前的登录流程
- 用户使用账号密码登录,登录成功后 登录平台 将用户 cookie 到 .abc.com 域名下
- 统一登录 redirect 到业务的 x.xyz.cn
- 但由于跨站跟踪的限制,业务的 x.xyz.cn 无法从 .abc.com下拿到用户 cookie (一级域名、二级域名均不同)
- 最终导致在 jsonp 去校验登录状态(checkLogin) 时,不能用 token 去跟统一登录后台换取 userInfo,登录校验不通过 x.xyz.cn 会⼀值停留在 redirect ⻚⾯

为什么其它业务不出现上述情况?以 B 业务为例,看他们的登录方式:
- 用户使用账号密码登录 B,登录成功后 统一登录 将用户 cookieset 到 .abc.com 域名下
- 统一登录 redirect 到 B.abc.com 域名下
- 由于 B 与统一登录之间的 一级域名、二级域名均相同,B.abc.com 可以直接从 abc.com 下获取用户 token
最后通过 jsonp 去校验登录状态,用 token 去跟统一登录后台换取 userInfo
4、跨域问题解决方案
4.1 方案一
方案:将我们业务的顶级域名 从 .cn 换成 .com、将二级域名 .xyz 换成 .abc
优点:线上问题快速修复、解决跨域的根本问题
问题:需要申请新域名、业务i在各处的备案信息均需要修改
结果:产品经理、项目负责人等均否决此方案4.2 方案二(最终实现的方案)
4.2.1 基本思路
业务不直接从 .abc.com 域名下获取用户 token,而是通过 调接口的方式 去获取用户t oken
4.2.2 实现流程

业务访问统一登录页面时,链接处携带 \withticket=true 参数,告知统一登录 业务的登录方式
- 统一登录知悉此种登录方式后,将会生成一个 ticket(类似于一个id) 返回到统一登录前端
- 统一登录前端通过 redirect 方式将生成的 ticket 给到 业务前端
- 业务前端根据获得的 ticket 在 node 层换取用户token(调用平台 server 获取 token)
- 业务前端在拿到用户 token 后,再去获取 userInfo (调用平台 server )
业务前端重定向到业务的页面(redirect_url),把 userInfo 设置 cookie 到 browser 中
4.2.3 具体实现
业务前端拼接登录地址:登录域名+ ?withticket=true&redirect_url= + redirect 中继页 + 页面重定向 url
- withticket=true:告知统一登录业务将采用 ticket 的登录方式
- redirect 中继页:https://study.seewoedu.cn/redirect 用于截获 ticket 获取 token
- redirect 中继页中,有一个 redict controller,controller 将根据 ticket 去获取 token 、用 token 获取userInfo、set cookie
