Safari禁止第三方Cookie无法获取用户登录状态

最后更新时间: 2/1/2024, 6:26:08 PM

# 问题描述

在跨站(cross-site)情况下, 苹果Safari浏览器无法获取竹云IDaaS的用户登录状态接口(https://{domain_name}/api/v1/config/isLogin),而在Windows、安卓系统的浏览器上可以获取到用户的登录状态。

# 问题分析

目前各大浏览器厂商为了保护用户隐私,不断加强浏览器的安全限制。苹果Safari采用更加保守的Cookie安全策略,并默认开启“阻止跨网站跟踪”,禁止跨站访问第三方Cookie,而其它浏览器厂商后续也会陆续跟进限制,当前看只是时间问题。 Safari这个配置不影响直接使用统一登录页面集成的业务应用系统,但是对业务系统直接通过API调用IDaaS获取用户状态会有影响,因为Safari阻止IDaaS SSO Cookie跨站提交,造成调用获取用户状态接口永远返回未登录状态(fasle)。

# 解决方案

站在safari浏览器角度来看, 只要是涉及第三方站点cookie一律禁止。临时解决方案可以通知用户手工关闭“阻止跨网站跟踪”,但是对于用户的体验不佳。解决的问题根本在于如何将第三方(third party cookie)变成第一方(first party cookie),应用系统调用竹云IDaaS接口请求变成同站(same site)之间的接口访问,这样就不会触发浏览器的阻止第三方cookie规则。

例如,IDaaS默认分配给企业客户的域名是companyname.bccastle.com,应用系统的域名是app.companyname.com,通过IDaaS提供的自定义企业域名功能,将IDaaS的默认域名变成一个企业自身的域名地址,如login.companyname.com。

login.companyname.com    #企业自定义域名后的IDaaS服务
app.companyname.com      #应用系统的域名
1
2

⚠️浏览器的安全策略也在不断的变化,若干时间后文中所述内容可能不再适用

# 相关知识

涉及到前端技术时,同源(Same-Origin)和同站(Same-Site)是经常遇到的术语。

# 同源(Same Origin)

同源(origin)= 协议(scheme)+ 主机名(hostname)+ 端口号(port) 
1

当一个请求url的协议、域名、端口三者之间的任意一个与当前页面url不同即为跨源或跨域。 也就是说违反同源策略即为跨源或跨域(cross origin)

# 同站(Same Site)

Cookie的校验较宽松,Cookie只关注域名,忽略协议和端口,只要两个 URL 的 eTLD+1 相同即可,eTLD 表示有效顶级域名,注册于 Mozilla 维护的公共后缀列表(Public Suffix List)中,例如,.com、.co、.uk、.github.io 等。而 eTLD+1 则表示,有效顶级域名+二级域名,例如taobao.com等。 如:

www.taobao.com 和 www.baidu.com 是跨站, www.a.taobao.com 和 www.b.taobao.com 是同站 a.github.io和b.github.io是跨站

总结跨站如下

  • 两个URL顶级域名和二级域名不同就是跨站(也称第三方(Third-party)),跨站一定跨域,反之不成立。
  • 相同则是同站第一方(First-party)。

# 各场景总结

  • 同源时:cookie会自动读取与存储、发送

  • 跨域未跨站(同站)时:后端添加CORS响应头保证跨域请求正常,配合前端XHR.withCredentials=true即可正常发送cookie。

  • 跨域且跨站时(跨站一定跨域):添加SameSite=none;Secure(注意:即使设置 SameSite=None 后,Safari 也不发送 cookie,而其它浏览器目前暂时支持发送cookie);

    或者使用nginx反向代理,将跨站请求变成同站来解决cookie跨站问题。

另,网络上可能存在其它的workaround解决方案,但是随着浏览器厂商的不断加强安全限制,可能引起未知的兼容问题,需要应用开发者权衡利弊,三思而行。