开发者社区 > 博文 > 前端 | Chrome 80 中 Iframe cookie 无法携带的问题
分享
  • 打开微信扫码分享

  • 点击前往QQ分享

  • 点击前往微博分享

  • 点击复制链接

前端 | Chrome 80 中 Iframe cookie 无法携带的问题

  • 京东科技IoT团队
  • 2020-12-29
  • IP归属:未知
  • 588760浏览

    场景

    我们的页面使用 iframe 集成了第三方的页面,在 chrome 84 版本中页面白屏无法正常显示,部分 iframe 页面上显示错误码 401 未认证。

    在开发者工具 Application 中可以查看到 iframe 域下的 cookie 是存在的,但是发出的请求中并没有带上 cookie,所以导致认证失败,获取不到资源。

    原因

    从 Chrome 51开始,浏览器的 Cookie 新增加了一个 SameSite 属性,用来防止 CSRF 攻击和用户追踪。
    该设置当前默认是关闭的,但在 Chrome 80 之后,该功能默认已开启。

    SameSite 属性有三个属性值

    • Strict:完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie

    • Lax:大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。
      导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单iframeAJAXImage 是不会发送第三方 cookie 的。

    • None

    设置了 Strict 或 Lax 以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。

    在 iframe 中,即使 iframe 页面和 iframe 的服务器不存在跨域问题,但是当 iframe 发出请求时,iframe 的父级页面也就是当前网页的 URL 和请求目标并不同源,所以请求想要携带的 iframe 域下的 cookie 属于第三方 cookie,浏览器默认会禁止其携带。

    下面我们把场景简单复现出来。

    iframe 页面

    iframe_1

    父级容器页面

    home

    iframe 页面运行在 http://localhost:5000/test,我们在 domain = localhost 的 cookie 里手动写入了 a_id=xiaolong 可以看到,页面没有嵌入时,请求可以正常携带 cookie

    domain 设置时是不能设置端口号的

    7DB50740-0959-4C65-85CE-C0D32778744E

    8A92F1B2-688D-4960-A6A7-F428F4273493

    父级容器页面运行在 http://192.168.0.105:62871/home,此时 iframe 发出的请求并没有携带 cookie

    12DD1F04-EACA-4F85-81B4-ACAB48FD0A36

    然后我们又把父级容器的 URL 改成 http://localhost:62871/home,cookie 就可以携带了

    B3F100DB-FF66-442E-AB50-532DD98A20BD

    此时我们应该注意到,父级页面和 iframe 页面的域的端口号并不相同,但是域名相同也能携带 cookie
    所以准确的说,cookie 不能跨域名(跨站点),而不是 cookie 不能跨域,同一站点下的不同端口号的 cookie 是共享的。

    localstorage

    对于 localstorage,则是完全遵循跨域的特性, iframe 和父级容器页面即使域名相同,端口号不同,也是不会共享的。并且 iframe 中也可以正常设置和使用 localstorage。

    4C23F787-18B8-4ED1-8963-06C4CF506E9A

    解决

    可以打开 chrome://flags/#same-site-by-default-cookies 手动将其暂时关闭 SameSite,但这并不是解决方案。

    1. 服务端 set-cookie 的时候,设置 SameSite 为 None,同时设置 Secure。且需要将后端服务域名必须使用 https 协议访问。SameSite 本来就是为了保障安全性的设置,现在又把其关闭。。。🤔

    2. 部署到同一个二级域名下,设置 domain,就不存在 cookie 跨域了

    3. 使用 Nginx 或其他网关工具进行 Proxy 操作

    4. 使用 token(jwt) 代替 cookie 方式作验证。

    参考:

    浏览器同源政策及其规避方法

    Cookie 的 SameSite 属性

    作者: 熊枭龙

    共0条评论