浏览器 WebView cookie 详解

一、什么是cookie

早期的web页面面临最大的问题之一就是如何维持状态,即服务器无法知道两个请求是否来自同一个浏览器。之前,最简单的方法就是在请求的页面中插入一个token,然后在下次请求时将这个token返回至服务器。或者将token放在URL的query字符串中来传递。这两种方法都需要手动操作,极易出错,且安全风险极大。
为了解决此类问题,cookie的概念被提出,并应用。cookie就是浏览器存储的一小段文本文件,存储于浏览器安装目录下的cookie文件夹。cookie是纯文本格式,不包含任何可执行代码。web页面或者服务器告知浏览器按照一定规范来存储这些信息,并在随后的请求中将这些信息发送至服务器,web服务器可以使用这些信息来识别不同用户。

二、cookie是如何工作的

当网页要发起网络请求时,浏览器会先检查是否有对应domain的cookie,有则自动添加在request header中的cookie字段中。这些都是浏览器自动帮我们做的,而且每一次网络请求浏览器都会自动帮我们做。
由于存储在cookie中的数据,每次网络请求都会被浏览器自动放在request header中,所以什么样的数据适合存储在cookie中很重要。cookie中适合存储每个请求都要发送给服务端的数据,比如身份认证信息以及其他基础信息,浏览器自动处理大大免去了重复添加的操作。cookie标准限值每个域名下的cookie大小最大为4KB,超出该限制的cookie会被截掉并且不会发送至服务器。每个域名下的cookie数量最多为20个,但是跟多浏览器厂商实现时支持大于20个。

三、cookie的格式

在Chrome浏览器开发者模式下的console中执行 document.cookie 即可获得当前页面domain下浏览器cookie,此方法只能获取非HttpOnly类型的cookie。
cookie为一段字符串,由键值对 key=value构成,键值对之间由一个分号和一个空格隔开。

示例:"PSTM=1560166948; BD_UPN=123253; H_PS_PSSID=1459_21105_30211_30087_30071"

cookie的属性选项

每个cookie都有属性,标识其过期时间,发送的域名路径,是否安全等。在设置cookie时都可以设置相关的属性,不设置则使用这些属性的默认值。在设置这些属性时,属性之间由一个分号和一个空格隔开。

如:"key=name; expires=2020-12-01T09:31:28.943Z; domain=.baidu.com; path=/; secure; HttpOnly"

1.expires / max-age

expires 选项用来设置cookie的过期时间,其格式必须是GMT格式的时间。对于失效的cookie浏览器会清空。如果没有设置该选项,则默认有效期为session,即会话cookie,浏览器关闭时会将会话cookie清空。
新的http/1.1协议中expires已经由max-age替代,两者不同点在于 expires为一个时间点,即cookie的失效时刻=expires,而max-age为一个以秒为单位的时间段,即cookie失效时间=创建时间+max-age。
max-age的默认值为-1,即session cookie。值为0时代表删除cookie。大于0 的值时cookie失效时间=创建时间+max-age。

2.domain 和 path

domain和path 共同决定了cookie会被自动添加到哪个或者哪些接口的request header中,如果没有设置这两个选项,则会使用默认值。domain默认值为设置该cookie的网页所在的域名,path默认值为设置该cookie的网页所在的目录。
例如:某cookie的domain为baidu.com,path为/,若请求的URL的域名为baidu.com或者其子域名,且URL的路径为"/"或者子路径,则浏览器会将此cookie添加到该请求的request header中。
该规则必须是同域的请求,即网络请求域名和页面域名必须是一样的,发生跨域请求时,即使请求接口域名和路径都满足cookie的domain和path,默认情况下也不会自动添加到请求头部中,详细可参考文章:你真的会使用XMLHTTPRequest吗 中关于跨域请求的部分。

3.secure

secure选项用来设置cookie只有在确保安全的请求中才会发送,例如https协议。
默认情况下,secure选项为空,即https与http协议都会将该cookie发送至服务端。在网页中设置secure类型的cookie时必须保证网页是https协议的,在http协议中无法设置secure类型的cookie。

4.HttpOnly

HttpOnly用来设置cookie能否通过js访问,包括读取、修改、删除等。默认HttpOnly选项为空,网页可以通过js访问该cookie。HttpOnly类型的cookie只能通过服务端来设置和读取。此类型的cookie比较安全,常用来做用户信息的存储。

5.SameSite

SameSite属性用来限制第三方cookie,减少安全风险。其可以设置三个值

  • Strict
    Strict最为严格,完全禁止第三方cookie,在跨域时,任何情况下都不会发送cookie。只有当请求和当前网页的URL域名一致时才会带上cookie。
  • Lax

    Lax稍微宽松,但是大多数情况下 也不会发送第三方cookie。发送cookie的只有导航到目标地址的GET请求,详见下表:
    image.png
  • None
    关闭SameSite属性,设置SameSite = None的前提是必须设置Secure属性。

四、如何设置cookie

cookie既可以由服务端来设置,也可以由前端来设置,但是HttpOnly的cookie只能由服务端设置。

1.服务端设置cookie

前端发送ajax请求,服务端都会返回response,response中有一项为set-cookie,是服务端用来设置cookie的。每次set只能设置一个cookie,在设置cookie内容的同时可以设置相关属性选项。如果要设置多个cookie,需要添加多个Set-Cookie字段.服务端可以设置cookie的所有属性:expires、domain、path、secure、HttpOnly、SameSite。

例如:
image.png
2.前端设置cookie

前端我们也可以通过执行document.cookie代码设置cookie。一次只能设置一个cookie,若要设置多个,则需要多次执行document.cookie方法。前端只可以设置expires、domain、path,以及在https协议的网页中设置secure。

代码示例:
document.cookie="age=26; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=baidu.com; path=/"
document.cookie="userid=oneuser; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=baidu.com; path=/"
document.cookie="nickname=may; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=baidu.com; path=/"

五、其他补充

1.cookie编码

cookie是一个字符串,且使用了逗号、分号、空格作为特殊字符,当cookie的key和value中包含了这个三个特殊字符时需要进行编码,一般使用escape进行编码,读取时使用unescape进行解码,也可以使用encodeURIComponent/decodeURIComponent或者encodeURI/decodeURI。

2.cookie何时会被覆盖

当name、domain、path都相同时。

3.关于domain的说明
  • 如果未设置cookie.domain ,则浏览器自动取URL的host作为domain值。
  • value值前边带点和不带点的区别,如:baidu.com 与 .baidu.com 。带点的值表示任何的子域名都可以访问;不带点的值表示只有完全一样的域名才能访问,子域名不能访问。

六、参考的一些资料

感谢以下文章的作者

  • https://segmentfault.com/a/1190000004556040
  • http://bubkoo.com/2014/04/21/http-cookies-explained/
  • http://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html
  • https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie

你可能感兴趣的:(浏览器 WebView cookie 详解)