Blog icon indicating copy to clipboard operation
Blog copied to clipboard

浏览器系列之 Cookie 和 SameSite 属性

Open mqyqingfeng opened this issue 4 years ago • 34 comments

前言

2 月份发布的 Chrome 80 版本中默认屏蔽了第三方的 Cookie,在灰度期间,就导致了阿里系的很多应用都产生了问题,为此还专门成立了小组,推动各 BU 进行改造,目前阿里系基本已经改造完成。所有的前端团队估计都收到过通知,也着实加深了一把大家对于 Cookie 的理解,所以很可能就此出个面试题,而即便不是面试题,当问到 HTTP 相关内容的时候,不妨也扯到这件事情来,一能表明你对前端时事的跟进,二还能借此引申到前端安全方面的内容,为你的面试加分。

所以本文就给大家介绍一下浏览器的 Cookie 以及这个"火热"的 SameSite 属性。

HTTP

一般我们都会说 “HTTP 是一个无状态的协议”,不过要注意这里的 HTTP 其实是指 HTTP 1.x,而所谓无状态协议,简单的理解就是即使同一个客户端连续两次发送请求给服务器,服务器也识别不出这是同一个客户端发送的请求,这导致的问题就比如你加了一个商品到购物车中,但因为识别不出是同一个客户端,你刷新下页面就没有了……

Cookie

为了解决 HTTP 无状态导致的问题,后来出现了 Cookie。不过这样说可能会让你产生一些误解,首先无状态并不是不好,有优点,但也会导致一些问题。而 Cookie 的存在也不是为了解决通讯协议无状态的问题,只是为了解决客户端与服务端会话状态的问题,这个状态是指后端服务的状态而非通讯协议的状态。

Cookie 介绍

那我们来看下 Cookie,引用下维基百科:

Cookie(复数形态Cookies),类型为「小型文本文件」,指某些网站为了辨别用户身份而储存在用户本地终端上的数据。

作为一段一般不超过 4KB 的小型文本数据,它由一个名称(Name)、一个值(Value)和其它几个用于控制 Cookie 有效期、安全性、使用范围的可选属性组成,这些涉及的属性我们会在后面会介绍。

Cookie 的查看

我们可以在浏览器的开发者工具中查看到当前页面的 Cookie:

尽管我们在浏览器里查看到了 Cookie,这并不意味着 Cookie 文件只是存放在浏览器里的。实际上,Cookies 相关的内容还可以存在本地文件里,就比如说 Mac 下的 Chrome,存放目录就是 ~/Library/Application Support/Google/Chrome/Default,里面会有一个名为 Cookies 的数据库文件,你可以使用 sqlite 软件打开它:

存放在本地的好处就在于即使你关闭了浏览器,Cookie 依然可以生效。

Cookie 的设置

那 Cookie 是怎么设置的呢?简单来说就是

  1. 客户端发送 HTTP 请求到服务器
  2. 当服务器收到 HTTP 请求时,在响应头里面添加一个 Set-Cookie 字段
  3. 浏览器收到响应后保存下 Cookie
  4. 之后对该服务器每一次请求中都通过 Cookie 字段将 Cookie 信息发送给服务器。

我们以 https://main.m.taobao.com/ 为例来看下这个过程:

我们在请求返回的 Response Headers 可以看到 Set-Cookie 字段:

然后我们查看下 Cookie:

我们刷新一遍页面,再看下这个请求,可以在 Request Headers 看到 cookie 字段:

Cookies 的属性

在下面这张图里我们可以看到 Cookies 相关的一些属性:

这里主要说一些大家可能没有注意的点:

Name/Value

用 JavaScript 操作 Cookie 的时候注意对 Value 进行编码处理。

Expires

Expires 用于设置 Cookie 的过期时间。比如:

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

当 Expires 属性缺省时,表示是会话性 Cookie,像上图 Expires 的值为 Session,表示的就是会话性 Cookie。当为会话性 Cookie 的时候,值保存在客户端内存中,并在用户关闭浏览器时失效。需要注意的是,有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期 Cookie 也会被保留下来,就好像浏览器从来没有关闭一样。

与会话性 Cookie 相对的是持久性 Cookie,持久性 Cookies 会保存在用户的硬盘中,直至过期或者清除 Cookie。这里值得注意的是,设定的日期和时间只与客户端相关,而不是服务端。

Max-Age

Max-Age 用于设置在 Cookie 失效之前需要经过的秒数。比如:

Set-Cookie: id=a3fWa; Max-Age=604800;

Max-Age 可以为正数、负数、甚至是 0。

如果 max-Age 属性为正数时,浏览器会将其持久化,即写到对应的 Cookie 文件中。

当 max-Age 属性为负数,则表示该 Cookie 只是一个会话性 Cookie。

当 max-Age 为 0 时,则会立即删除这个 Cookie。

假如 Expires 和 Max-Age 都存在,Max-Age 优先级更高。

Domain

Domain 指定了 Cookie 可以送达的主机名。假如没有指定,那么默认值为当前文档访问地址中的主机部分(但是不包含子域名)。

像淘宝首页设置的 Domain 就是 .taobao.com,这样无论是 a.taobao.com 还是 b.taobao.com 都可以使用 Cookie。

在这里注意的是,不能跨域设置 Cookie,比如阿里域名下的页面把 Domain 设置成百度是无效的:

Set-Cookie: qwerty=219ffwef9w0f; Domain=baidu.com; Path=/; Expires=Wed, 30 Aug 2020 00:00:00 GMT

Path

Path 指定了一个 URL 路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部。比如设置 Path=/docs/docs/Web/ 下的资源会带 Cookie 首部,/test 则不会携带 Cookie 首部。

Domain 和 Path 标识共同定义了 Cookie 的作用域:即 Cookie 应该发送给哪些 URL。

Secure属性

标记为 Secure 的 Cookie 只应通过被HTTPS协议加密过的请求发送给服务端。使用 HTTPS 安全协议,可以保护 Cookie 在浏览器和 Web 服务器间的传输过程中不被窃取和篡改。

HTTPOnly

设置 HTTPOnly 属性可以防止客户端脚本通过 document.cookie 等方式访问 Cookie,有助于避免 XSS 攻击。

SameSite

SameSite 是最近非常值得一提的内容,因为 2 月份发布的 Chrome80 版本中默认屏蔽了第三方的 Cookie,这会导致阿里系的很多应用都产生问题,为此还专门成立了问题小组,推动各 BU 进行改造。

作用

我们先来看看这个属性的作用:

SameSite 属性可以让 Cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)。

属性值

SameSite 可以有下面三种值:

  1. Strict 仅允许一方请求携带 Cookie,即浏览器将只发送相同站点请求的 Cookie,即当前网页 URL 与请求目标 URL 完全一致。
  2. Lax 允许部分第三方请求携带 Cookie
  3. None 无论是否跨站都会发送 Cookie

之前默认是 None 的,Chrome80 后默认是 Lax。

跨域和跨站

首先要理解的一点就是跨站和跨域是不同的。同站(same-site)/跨站(cross-site)」和第一方(first-party)/第三方(third-party)是等价的。但是与浏览器同源策略(SOP)中的「同源(same-origin)/跨域(cross-origin)」是完全不同的概念。

同源策略的同源是指两个 URL 的协议/主机名/端口一致。例如,https://www.taobao.com/pages/...,它的协议是 https,主机名是 www.taobao.com,端口是 443。

同源策略作为浏览器的安全基石,其「同源」判断是比较严格的,相对而言,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 是跨站(注意是跨站)。

改变

接下来看下从 None 改成 Lax 到底影响了哪些地方的 Cookies 的发送?直接来一个图表:

从上图可以看出,对大部分 web 应用而言,Post 表单,iframe,AJAX,Image 这四种情况从以前的跨站会发送三方 Cookie,变成了不发送。

Post表单:应该的,学 CSRF 总会举表单的例子。

iframe:iframe 嵌入的 web 应用有很多是跨站的,都会受到影响。

AJAX:可能会影响部分前端取值的行为和结果。

Image:图片一般放 CDN,大部分情况不需要 Cookie,故影响有限。但如果引用了需要鉴权的图片,可能会受到影响。

除了这些还有 script 的方式,这种方式也不会发送 Cookie,像淘宝的大部分请求都是 jsonp,如果涉及到跨站也有可能会被影响。

问题

我们再看看会出现什么的问题?举几个例子:

  1. 天猫和飞猪的页面靠请求淘宝域名下的接口获取登录信息,由于 Cookie 丢失,用户无法登录,页面还会误判断成是由于用户开启了浏览器的“禁止第三方 Cookie”功能导致而给与错误的提示

  2. 淘宝部分页面内嵌支付宝确认付款和确认收货页面、天猫内嵌淘宝的登录页面等,由于 Cookie 失效,付款、登录等操作都会失败

  3. 阿里妈妈在各大网站比如今日头条,网易,微博等投放的广告,也是用 iframe 嵌入的,没有了 Cookie,就不能准确的进行推荐

  4. 一些埋点系统会把用户 id 信息埋到 Cookie 中,用于日志上报,这种系统一般走的都是单独的域名,与业务域名分开,所以也会受到影响。

  5. 一些用于防止恶意请求的系统,对判断为恶意请求的访问会弹出验证码让用户进行安全验证,通过安全验证后会在请求所在域种一个Cookie,请求中带上这个Cookie之后,短时间内不再弹安全验证码。在Chrome80以上如果因为Samesite的原因请求没办法带上这个Cookie,则会出现一直弹出验证码进行安全验证。

  6. 天猫商家后台请求了跨域的接口,因为没有 Cookie,接口不会返回数据

  7. ……

如果不解决,影响的系统其实还是很多的……

解决

解决方案就是设置 SameSite 为 none。

以 Adobe 网站为例:https://www.adobe.com/sea/,查看请求可以看到:

不过也会有两点要注意的地方:

  1. HTTP 接口不支持 SameSite=none

如果你想加 SameSite=none 属性,那么该 Cookie 就必须同时加上 Secure 属性,表示只有在 HTTPS 协议下该 Cookie 才会被发送。

  1. 需要 UA 检测,部分浏览器不能加 SameSite=none

IOS 12 的 Safari 以及老版本的一些 Chrome 会把 SameSite=none 识别成 SameSite=Strict,所以服务端必须在下发 Set-Cookie 响应头时进行 User-Agent 检测,对这些浏览器不下发 SameSite=none 属性

Cookie 的作用

Cookie 主要用于以下三个方面:

  1. 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  2. 个性化设置(如用户自定义设置、主题等)
  3. 浏览器行为跟踪(如跟踪分析用户行为等)

Cookie 的缺点

如果被问到话,可以从大小、安全、增加请求大小等方面回答。

参考

  1. MDN
  2. HTTP是一个无状态的协议。这句话里的无状态是什么意思? - 灵剑的回答 - 知乎
  3. Chrome 80.0中将SameSite的默认值设为Lax,对现有的Cookie使用有什么影响? - 紫云飞的回答 - 知乎
  4. 一些内部文章

各种系列

各种系列文章目录地址:https://github.com/mqyqingfeng/Blog

如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者 有所启发,欢迎 star,对作者也是一种鼓励。

mqyqingfeng avatar Mar 18 '20 03:03 mqyqingfeng

之前还不行呢,好几天了;什么也没操作,看完这篇文章就好了,是不是那个cookie是登陆淘宝时那个页面设置的?

qinyakang avatar Mar 18 '20 10:03 qinyakang

@qinyakang 是哪个页面不行了?请求淘宝的登录会把 cookie 种到淘宝的域下,然后会用一些方法同步到独立域名

mqyqingfeng avatar Mar 19 '20 12:03 mqyqingfeng

@qinyakang 是哪个页面不行了?请求淘宝的登录会把 cookie 种到淘宝的域下,然后会用一些方法同步到独立域名

就是本地调试时用Chrome打开,在test.taobao.com下一直重定向到登录页面,不得已下载火狐浏览器调试;我知道是cookie没带过去导致的,浏览器的设置看了个遍也没弄好,然后就看到这篇文章;再一打开就好了,应该是服务端在我登录时把SameSite设置为none了;;

qinyakang avatar Mar 19 '20 13:03 qinyakang

zan

OldSixLi avatar Mar 20 '20 07:03 OldSixLi

想请教一下,如果是内网域名,没有办法用eTLD的方式判断跨站,那浏览器要怎么做判断呢?

yykoypj avatar Mar 22 '20 08:03 yykoypj

想请教一下,如果是内网域名,没有办法用eTLD的方式判断跨站,那浏览器要怎么做判断呢?

我写自己搭博客的时候,是用http + ip访问的,后端接口部署在非80端口上,cookie就被禁止跨域发送了。后来搞了反向代理,接口也走80端口,才正常。所以应该是 根据 ip + port 判断。

OldDream avatar Mar 25 '20 07:03 OldDream

@OldDream 哈哈哈 你说的这个是跨域的情况。 我当时这么问是不懂domain的前缀带点的cookie的具体情况,比如.abc.def,这个cookie在xxx.abc.def这样的路由下,也算是同站cookie。 只是我当时看规范说不应该支持这种前缀带点的domain书写方式,规范里说的是会直接忽略该点,按照规范做是有一大堆的cookie会变成跨站cookie并且在没有设置sameSite=None的情况下不会被发送出去,只是大多数浏览器都支持前缀带点,并且没谁说将会取消该支持,所以只是我被自己绕进去了而已..

yykoypj avatar Mar 25 '20 07:03 yykoypj

@OldDream 哈哈哈 你说的这个是跨域的情况。 我当时这么问是不懂domain的前缀带点的cookie的具体情况,比如.abc.def,这个cookie在xxx.abc.def这样的路由下,也算是同站cookie。 只是我当时看规范说不应该支持这种前缀带点的domain书写方式,规范里说的是会直接忽略该点,按照规范做是有一大堆的cookie会变成跨站cookie并且在没有设置sameSite=None的情况下不会被发送出去,只是大多数浏览器都支持前缀带点,并且没谁说将会取消该支持,所以只是我被自己绕进去了而已..

OldDream avatar Mar 25 '20 08:03 OldDream

a.github.io 和 b.github.io 是跨站(注意是跨站)

这个确实学到了, 顶级域名和有效顶级域名的区别。 比如 严格来说 .cn 是顶级域名, 但我们常见 .com.cn .org.cn, 这些都是 .cn 自主创造出来的顶级域名,由于这样情况非常广泛,所以严格意义的顶级域名很多场景下没法直接使用,我们就创造了一个【有效顶级域名】的概念。一样的道理, 组织也可以把自己的根域 注册成 有效顶级域名, 比如说 github.io, compute.amazonaws.com 这种。

materliu avatar Mar 27 '20 08:03 materliu

image 这里是跨域吧,楼主是笔误了吧😂

hushengNo1 avatar Mar 30 '20 13:03 hushengNo1

image 这里是跨域吧,楼主是笔误了吧

是跨站,你仔细看上一段,判断是否跨站不是根据顶级域名(TLD)来判断,是根据有效顶级域名(eTLD)来判断

github.io是一个完整的 eTLD,其上注册的子域名都是跨站

sagnitude avatar Mar 31 '20 08:03 sagnitude

我想说,同时设置 http-only 和 secure是不是重复了呢? 因为 secure 代表只有 https 协议才会发送cookie,http-only 代表仅当 http 和 https 协议下才发送 cookie,本地方式获取 cookie 无效,可以总结为下面这张表:

| http | https | 本地 |

------------- | ------------- | ------------- | ------------- | http-only | ✔ | ✔ | × | secure | × | ✔ | × |

可以看出 secure 的作用范围是 http-only 的子集,所以我觉得如果 这两者一起写的话就重复了,代码不够简洁,但是因为各种历史原因和老浏览的兼容等等问题,我不确定上述表格是否完全适用于所有情况,而且 secure 协议本身就有限制,在非安全站点(http://)已经不能再在 cookie 中设置 secure 了(在Chrome 52+ and Firefox 52+ 中新引入的限制)。

所以就想说,可能因为历史原因,即使结果重复了,也有同时写在一起的必要性,但这也为日后优化方向提供了思路,比如现在两者共存的情况下,secure 的优先级永远高于 http-only(取其交集而不是并集)。

ykl124 avatar Apr 02 '20 11:04 ykl124

我想说,同时设置 http-only 和 secure是不是重复了呢? 因为 secure 代表只有 https 协议才会发送cookie,http-only 代表仅当 http 和 https 协议下才发送 cookie,本地方式获取 cookie 无效,可以总结为下面这张表:

| http | https | 本地 |

------------- | ------------- | ------------- | ------------- | http-only | ✔ | ✔ | × | secure | × | ✔ | × |

可以看出 secure 的作用范围是 http-only 的子集,所以我觉得如果 这两者一起写的话就重复了,代码不够简洁,但是因为各种历史原因和老浏览的兼容等等问题,我不确定上述表格是否完全适用于所有情况,而且 secure 协议本身就有限制,在非安全站点(http://)已经不能再在 cookie 中设置 secure 了(在Chrome 52+ and Firefox 52+ 中新引入的限制)。

所以就想说,可能因为历史原因,即使结果重复了,也有同时写在一起的必要性,但这也为日后优化方向提供了思路,比如现在两者共存的情况下,secure 的优先级永远高于 http-only(取其交集而不是并集)。

http-only 无法被网页脚本读取,不限制传输通路的安全性 secure 可以被网页脚本读取,只允许通过安全通路发送给服务器

sagnitude avatar Apr 02 '20 12:04 sagnitude

解决 解决方案就是设置 SameSite 为 none

这种方案作为临时性解决方案尚可, 个人认为不是正确的做法, 太过于简单粗暴, 相当于又让Cookies安全回退到最初的状态了, 不可以推广使用.

合理的解决方案简单总结应该是:

  1. CSRF Token会话类Cookies设置Strict
  2. 默认保持Lax
  3. 如果需要cookies追踪等需要第三方站点使用的cookies可以设置为None

临时性解决问题没问题, 但是从技术角度来说, 应该严格按照这个标准来做.

PS: 这个方案更多的是解决一些安全性差的网站和用户, 对于淘宝等大网站而言确属只能属于增益, 因为这种安全防护只是处于客户端层面, 并不是所有用户的客户端都是安全的.

个人的一些看法.

Sep0lkit avatar Apr 18 '20 05:04 Sep0lkit

Samesite=None的UA列表可以看这里得知:https://www.chromium.org/updates/same-site/incompatible-clients

Rockergmail avatar Jun 21 '20 13:06 Rockergmail

image

这张图我有一些疑问:

  1. a 链接会发 cookie 吗,怎么发,点击之后发?这和我直接打开一个页面有啥区别?
  2. script 外链标签会携带 cookie 吧,为啥没列出来呢
  3. ajax 包括 fetch 吗?
  4. link 是只有预加载才发吗,普通的 link 标签呢?
  5. audio、video、flash 这些资源应该是和图片一样的吧?

gongshun avatar Sep 03 '20 04:09 gongshun

那如果是http的请求,设置samesite不生效,除了修改浏览器SameSite by default cookies 设置,还有什么办法么

jackmovestart avatar Sep 23 '20 11:09 jackmovestart

那如果是http的请求,设置samesite不生效,除了修改浏览器SameSite by default cookies 设置,还有什么办法么

nginx反向代理,跨域变同域试试

finger92 avatar Sep 27 '20 05:09 finger92

楼主 想请问下这种情况需不需要处理 A、B两个页面 B页面作为iframe嵌入A页面 A的域名是 1111.taobao.com B的域名是2222.taobao.com 那么 B页面发送请求的时候会带上A页面的cookie嘛?

junjiebyr avatar Feb 02 '21 06:02 junjiebyr

我想说,同时设置 http-only 和 secure是不是重复了呢? 因为 secure 代表只有 https 协议才会发送cookie,http-only 代表仅当 http 和 https 协议下才发送 cookie,本地方式获取 cookie 无效,可以总结为下面这张表:

| http | https | 本地 |

------------- | ------------- | ------------- | ------------- | http-only | ✔ | ✔ | × | secure | × | ✔ | × |

可以看出 secure 的作用范围是 http-only 的子集,所以我觉得如果 这两者一起写的话就重复了,代码不够简洁,但是因为各种历史原因和老浏览的兼容等等问题,我不确定上述表格是否完全适用于所有情况,而且 secure 协议本身就有限制,在非安全站点(http://)已经不能再在 cookie 中设置 secure 了(在Chrome 52+ and Firefox 52+ 中新引入的限制)。

所以就想说,可能因为历史原因,即使结果重复了,也有同时写在一起的必要性,但这也为日后优化方向提供了思路,比如现在两者共存的情况下,secure 的优先级永远高于 http-only(取其交集而不是并集)。

secure 和 httponly 干的不是一件事 secure 管的是传输协议,设置了 secure 的 cookie 只能在 https 下传输 httponly 管的是可见性,设置了 httponly 的 cookie 对 js 脚本不可见

edwardzjl avatar Feb 04 '21 03:02 edwardzjl

Chrome在7月份底公布,Chrome 85对Referrer-Policy调整,默认由于no-referrer-when-downgrade调整为strict-origin-when-cross-origin,测试版将于2020年7月发布,稳定版将于2020年8月发布。

同个主域之前是没有影响,但是不同主域之前的就是有影响,比如从A网站跳转到B网站的时候就有些不同的了。

这个问题也反馈推动改进下啊,现在Chrome 90无法登陆淘宝,静态跨越资源无法加载

flyingfishchen avatar Apr 27 '21 15:04 flyingfishchen

需要 UA 检测,部分浏览器不能加 SameSite=none IOS 12 的 Safari 以及老版本的一些 Chrome 会把 SameSite=none 识别成 SameSite=Strict,所以服务端必须在下发 Set-Cookie 响应头时进行 User-Agent 检测,对这些浏览器不下发 SameSite=none 属性

这里有人测试过具体的 UA 是多少嘛?可以针对这个做下专门的处理

loo2k avatar Jul 08 '21 08:07 loo2k

那如果是ip地址的话,主机相同、端口不同算跨站吗

zhaoyan11 avatar Dec 01 '21 09:12 zhaoyan11

@zhaoyan11 算跨域,不算跨站

mqyqingfeng avatar Dec 02 '21 02:12 mqyqingfeng

http 无状态针对 1.x 怎么理解?2.0 有新变化吗

fatFire avatar Jun 22 '22 03:06 fatFire

还有个问题就是 taobao.com 网站下的cookie 的 domain 设置成 .mmstat.com 是可以的吗?也就是说,第三方 cookie 是怎么在第一方网站上种下的。

fatFire avatar Jun 22 '22 06:06 fatFire

还有个问题就是 taobao.com 网站下的cookie 的 domain 设置成 .mmstat.com 是可以的吗?也就是说,第三方 cookie 是怎么在第一方网站上种下的。

  1. 應該不行吧 只能設置第一方 cookie (same-site)
  2. 假設 第一方網站叫做 A 網站 ,第三方網站叫做 B 網站 當你曾經拜訪過 B 網站,B網站的 response header 裏面有 set-cookie 就會種下 cookie, 然後當你瀏覽 A網站的時候,如果 A網站有發請求至 B網站,會根據當初 B 網站的 set-cookie 設定,決定能不能送出當初被 B網站種下的 cookie.

Jadenhub avatar Jun 25 '22 09:06 Jadenhub

楼主 想请问下这种情况需不需要处理 A、B两个页面 B页面作为iframe嵌入A页面 A的域名是 1111.taobao.com B的域名是2222.taobao.com 那么 B页面发送请求的时候会带上A页面的cookie嘛?

@junjiebyr 1111.taobao.com 和 2222.taobao.com 是同站,会带

gqbre avatar Jul 06 '22 10:07 gqbre

这里不太严谨感觉,应该不是相同的Url,而是相同的站点 比如 url1= www.baidu.com/send 和 url2 = www.baidu.com/wait 虽然url不是完全相等的,但是站点相等也是可以发送的 image

1725636955 avatar Sep 03 '22 04:09 1725636955

有一点不是很理解,购物车那里,直接拿用户 id 去获取购物车信息不就行了吗,和 cookie 有什么关系呢?

DaphnisLi avatar Dec 21 '22 02:12 DaphnisLi