Cookie详解

文章目录

  • Cookie属性
    • 1.Name
    • 2.Value
    • 3.Domain
    • 4.Path
    • 5.Expires/Max-age
    • 6.Size
    • 7.HttpOnly
    • 8.Secure
    • 9.Priority
    • 10.SameSite
    • 11.SameParty
  • Cookie的传输
  • Cookie的编解码
  • Cookie的弊端
  • 同一Cookie认定
  • Cookie的删除


Cookie属性

在这里插入图片描述
上图是Chrome浏览器中的Cookie截图,cookie的属性:Name、Value、Domain、Path、Expires/Max-age、Size、HttpOnly、Secure、SameSite、SameParty、Priority。下面依次介绍这些属性。

1.Name

Name是Cookie的名称,Cookie一旦创建,名称便不可更改,一般名称不区分大小写。

2.Value

Value是cookie名称Name对应的Cookie的值,如果值为Unicode字符,需要为字符编码。如果值为二进制数据,则需要使用BASE64编码。

3.Domain

指定Cookie的有效域,决定在向该域发送请求时是否携带此Cookie。Domain属性的默认值是创建cookie的网页所在服务器的主机名。不能将一个cookie的域设置成服务器所在的域之外的域。Domain的设置是对子域生效的,如Doamin设置为 .a.com,则b.a.com和c.a.com均可使用该Cookie,但如果设置为b.a.com,则c.a.com不可使用该Cookie。

注意:在RFC2109规范,没有前导点的域意味着不能在子域上使用它,而只有一个前导点(.a.com)允许跨子域使用。然而,现代浏览器尊重更新的规范RFC6265,并将忽略任何前导点,这意味着您可以在子域和顶级域上使用cookie。如果你设置了一个cookie的Domain为a.com,那么b.a.com、c.a.com都可以使用该cookie。

在tomcat8.5版本后Domain规则:

  1. 必须是1-9、a-z、A-Z、. 、- (注意是-不是_)这几个字符组成
  2. 必须是数字或字母开头
  3. 必须是数字或字母结尾

Tomcat更换默认的 CookieProcessor 实现为 Rfc6265CookieProcessor ,之前的实现为 LegacyCookieProcessor 。

LegacyCookieProcessor 主要是实现了标准RFC6265, RFC2109 和 RFC2616,而Rfc6265CookieProcessor是实现了标准RFC6265。

Rfc6265CookieProcessor拼接Domain时增加了对domain 的校验(Rfc6265CookieProcessor类的validateDomain(String domain)方法),即必须以数字或者字母开头,必须以数字或者字母结尾,不支持Domain以.开头。

如果一定要支持设置.开头的Domain,有一下几种方式:

  1. 直接修改Tomcat安装目录下的conf\context.xml文件,指定cookie处理器为 org.apache.tomcat.util.http.LegacyCookieProcessor

     <Context>
        <CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
     </Context>
    
    
  2. 如果使用的是SpringBoot,直接指定容器中的cookie处理器。

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
        return (factory) -> factory.addContextCustomizers((context) -> 
                context.setCookieProcessor(new LegacyCookieProcessor()));
    }
    

domain对浏览器写入cookie的影响(例如当前域为a.test.com):

传入domain值 写入结果 写入domain值
成功 a.test.com
a.test.com 成功 .a.test.com
.a.test.com 成功 .a.test.com
b.test.com 失败
.b.test.com 失败
test.com 成功 .test.com
.test.com 成功 .test.com
www.test.com 失败
www.qq.com 失败

归纳总结:

  1. 不传domain,默认当前域名;
  2. 只要传了domain,如果不是以.开头,都会强制在前面加上一个.,不管是一级还是二级域名;
  3. domain只能“小于等于”当前域名,否则写入不成功;

其他注意事项:

  • .test.com下的cookie在a.test.com下可以获取到(也就是说可以被下级域名正确获取到),但是test.com下的cookie在a.test.com下获取不到。

4.Path

指定Cookie的有效路径,和Domain类似,也对子路径生效,如Cookie1和Cookie2的Domain均为a.com,但Path不同,Cookie1的Path为 /b/,而Cookie的Path为 /b/c/,则在a.com/b页面时只可以访问Cookie1,在a.com/b/c页面时,可访问Cookie1和Cookie2。Path属性需要使用符号“/”结尾。

5.Expires/Max-age

Expires和Max-age均为Cookie的有效期.

  • Expires:HTTP/1.0中定义,Cookie过期的绝对时间(GMT格式)。若设置为以前的时间,则该Cookie立刻被删除,若不设置则默认页面关闭时删除该Cookie。

    Expires = 当时服务器的时间+有效时间

  • Max-age:HTTP/1.1中定义,Cookie存活的相对时间(单位秒,如:3600),表示多少秒之后失效。若Max-age设置为0,则立刻失效,设置为负数,则在页面关闭时失效。Max-age默认为 -1。

    如果max-age为0,则表示删除该cookie。cookie机制没有提供删除cookie的方法,因此通过设置该cookie即时失效实现删除。

HTTP/1.1后使用Max-age来替换Expires,但为了向下兼容,一般Expires、Max-age会同时存在。

Expires的缺点:返回的到期时间是服务端的时间,如果客户端的时间与服务端的时间相差很大,那么误差就很大。例如:

  • 服务端当前时间2022-10-15 08:00:00,cookie的有效时间为10秒,服务端返回的Expires就为2022-10-15 08:00:10
  • 如果客户端与服务时间有差距,客户端当前时间为2022-10-15 08:00:15。客户端得到服务端返回的Expires,发现cookie已经失效了,这显然是不合理。

6.Size

Size是此Cookie的大小。在所有浏览器中,任何cookie大小超过限制都被忽略,且永远不会被设置。各个浏览器对Cookie的最大值和最大数目有不同的限制。

浏览器 Cookie最大条数 Cookie最大长度(单位:字节)
IE 50 4095
Chrome 150 4096
FireFox 50 4097
Opera 30 4096
Safari 无限制 4097

7.HttpOnly

用于避免cookie被Javascript访问,值为 true 或 false,默认false。若设置为true,则不允许通过脚本document.cookie去更改这个值,同样这个值在document.cookie中也不可见,但在发送请求时依旧会携带此Cookie。

8.Secure

Cookie的安全属性,用于指定cookie需要通过安全Socket层连接传递。值为 true 或 false,默认值false,若设置为true,则浏览器只会在HTTPS和SSL等安全协议中传输此Cookie,不会在不安全的HTTP协议中传输此Cookie。

9.Priority

优先级,chrome的提案,定义了三种优先级,Low/Medium/High,当cookie数量超出时,低优先级的cookie会被优先清除。
在3其他浏览器中,不一定存在Priority属性。

10.SameSite

SameSite用来限制第三方 Cookie,从而减少安全风险。它有3个属性,分别是:

  1. Strict
    Scrict最为严格,完全禁止第三方Cookie,跨站点时,任何情况下都不会发送Cookie
  2. Lax
    Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。
  3. None
    网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。

11.SameParty

暂无

Cookie的传输

浏览器将cookie信息以name=value对的形式存储于本地,每当请求新文档时,浏览器将发送Cookie,目的是让Server可以通过HTTP请求追踪客户。所以从WEB性能的角度来说我们要尽量的减小cookie,以达到传输性能的最大化。

浏览器对于Web服务器应答包头中Cookie的操作步骤:

  1. 从Web服务器的应答包头中提取所有的cookie。
  2. 解析这些cookie的组成部分(名称,值,路径等等)。
  3. 判定主机是否允许设置这些cookie。允许的话,则把这些Cookie存储在本地。

浏览器对Web服务器请求包头中所有的Cookie进行筛选的步骤:

  1. 根据请求的URL和本地存储cookie的属性,判断那些Cookie能被发送给Web服务器。
  2. 对于多个cookie,判定发送的顺序。
  3. 把需要发送的Cookie加入到请求HTTP包头中一起发送。

Cookie的编解码

cookie的名/值中的值不允许包含分号,逗号和空格符,为了最大化用户代理和服务器的兼容性,任何被存储为 cookie 值的数据都应该被编码,例如用我们前端熟知的js全局函数encodeURIComponent编码和decodeURIComponent解码。

Cookie的弊端

每次新的请求,浏览器都会发送Cookie到服务器,导致WEB性能下降。所以不建议将cookie作为客户端存储一种实现方案。

同一Cookie认定

  1. name、domain、path这三个参数的值都相同,才属于同一cookie;
  2. name、domain、path这三个参数只要有一个的值不同,都不属于同一cookie;

Cookie的删除

cookie机制没有提供删除cookie的方法,因此通过设置该cookie即时失效实现删除。
max-age为0,或者Expires为一个已过期时间,则表示删除该cookie。

常见cookie删除无效问题:
一般是因为删除时指定的name、domain、path这三个参数的值与需要删除的cookie这三个参数的值有不同。

你可能感兴趣的:(HTTP,cookie)