写点什么

HTTP 系列之:HTTP 中的 cookies

发布于: 56 分钟前

简介

如果小伙伴最近有访问国外的一些标准网站的话,可能经常会弹出一个对话框,说是本网站为了更好的体验和跟踪,需要访问你的 cookies,问你同意不同意,对于这种比较文明的做法,我一般是点同意的。

但是转头一想,为什么访问国内的网站从来没有弹出过这个提示呢?这是一个值得深思的问题,或许当你看完这篇文章之后,就有了答案。

cookies 的作用

那么 cookies 有什么作用呢?HTTP cookies 就是服务器端发送给浏览器端的一小部分数据,浏览器接收到这个数据之后,可以存起来自己用,也可以在后续发送到 server 端进行一些数据的校验。

通过在 cookies 中存储一些有用的数据,可以将无状态的 HTTP 协议变成有状态的 session 连接,或者用来保存登录的权限,下次不用密码即可登陆,非常有用。

一般来说,cookies 用在三个方面:

  1. session 的管理,用来保存登录状态,从而让 HTTP 请求可以带上状态信息。

  2. 用户自定义的设置,这些用户特殊的字段,需要保存在 cookies 中。

  3. 跟踪用户的行为信息。

在很久很久以前,还没有现代浏览器的时候,客户端的唯一存储就是 cookies,所以 cookies 也作为客户端存储来使用的,但是有了现代的浏览器之后,一般是建议把客户端存储的数据放到其他存储方式中。

为什么呢?

因为每次请求 cookies 中的数据会自动带上,并且发送到 server 端,所以如果 cookies 中存储了太多的数据,就会导致服务器性能的下降。

创建 cookies

因为 cookies 是客户端的本地存储,所以如果服务器端想要设置客户端的 cookies 时,通过在响应头中设置 Set-Cookie,浏览器接收到这个响应头之后,就会将对应的 cookies 内容存储到浏览器本地。

然后在后续的服务器请求中都会带上 Cookie header。同时 cookie 还可以带上过期时间、发送限制等属性。

先来看下 Set-Cookie 的格式:

Set-Cookie: <cookie-name>=<cookie-value>
复制代码

举个例子,下面是一个 server 端的响应:

HTTP/2.0 200 OKContent-Type: text/htmlSet-Cookie: name=flydeanSet-Cookie: site=www.flydean.com

复制代码

当浏览器接收到这个响应之后,就会在本地的 cookies 中设置对应的值,并且在后续的请求中将这些值以 cookies 的 header 形式带上:

GET /test.html HTTP/2.0Host: www.flydean.comCookie: name=flydean; site=www.flydean.com
复制代码

在 netty 中提供了一个 Cookie 的类,专门用来表示 cookies,这个类中提供了 cookies 的基本属性,然后通过使用:

response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(cookie));

复制代码

来对响应头进行设置。

cookies 的生存时间

HTTP 的 cookies 有两种,一种是 session cookies,这种 cookies 会在 session 结束之后自行删除。

还有一种 cookies 通过指定 Expires 或者 Max-Age 来设置过期时间:

Set-Cookie: id=abcdef; Expires=Thu, 31 May 2021 08:00:00 GMT;
复制代码

其中 Expires 是 HTTP1.0 中定义的 header,Max-Age 是 HTTP1.1 中定义的 header。

cookies 的权限控制

HTTP 提供了两个属性来对 cookies 的权限进行控制,分别是 Secure 和 HttpOnly。

如果 cookies 中带有 Secure 属性,那么 cookies 只会在使用 HTTPS 协议的时候发送给服务器。如果使用的是 HTTP 协议,则不会发送 cookies 信息。

并且,如果是在 http 的情况下,server 端是不允许给 cookie 设置 Secure 属性的。

但是设置了 Secure 属性并不意味着 cookies 就是安全的,因为可以从其他的手段拿到浏览器端的 cookies。

还有一个属性是 HttpOnly,如果 cookies 设置了 HttpOnly,那么 cookies 是不允许被 JavaScript 访问的,通过设置 HttpOnly,我们可以提升客户端数据的安全性:

Set-Cookie: id=abcdef; Expires=Thu, 21 May 2021 08:00:00 GMT; Secure; HttpOnly
复制代码

cookies 还可以添加 Domain 和 Path 属性,用于标记 cookies 可以发送到的 URL。

其中 Domain 表示域名,而 Path 表示路径。

如果 Domain 没有设置,则默认是设置 cookies 的 host,这个 host 是不包含子 domain 的。如果手动指定了 Domain,那么子 domain 是会包含在内的。

比如如果我们设置了 Domain=flydean.com,那么子 domain:doc.flydean.com 也会共享这个 cookies。

Path 用来匹配 URL 的路径,只有匹配到的 URL 才可以发送 cookies。

另外 HTTP 还提供了一个 SameSite 属性,表示如果是在 CORS 环境情况下,是否发送 cookies 到第三方网站,这样可以在一定程度上保护网站的信息。

SameSite 有三个可能的值,分别是 Strict, Lax, 和 None。如果在 Strict 情况下,那么 cookie 仅发送到与创建它的站点相同的站点。Lax 跟 Strict 类似,不同之处在于当用户导航到 cookie 的原始站点时发送 cookie,比如通过访问外部站点的链接。 None 可以在原始网站和跨站资源访问中使用,但是必须要在安全的环境中进行(设置 Secure 属性)。如果没有设置 SameSite,那么表现是和 Lax 一致的。

例如:

Set-Cookie: name=flydean; SameSite=Strict
复制代码

第三方 cookies

我们知道 cookies 是和 domain 相关的,如果 cookies 的 domain 是和当前访问的页面相同的话,这个 cookies 就叫做 first-party cookies。如果和当前的访问页面不同,比如访问第三方的图片、脚本、css 等,第三方的服务器有可能会发送他们自己的 cookies,这种 cookies 叫做第三方 cookies,第三方 cookies 主要被用来广告或者跟踪用户的行为信息。

对于有些浏览器来说,可能会禁用第三方的 cookies,这有可能会导致访问网站的一些功能问题,大家可以主要观察一下。

总结

使用 cookies 可以辅助我们做很多事情,但是也要注意 cookies 的安全性。

本文已收录于 http://www.flydean.com/05-http-cookie/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

发布于: 56 分钟前阅读数: 3
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020.06.07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
HTTP系列之:HTTP中的cookies