一、什么是 Cookie?
Cookie 是通过浏览器将服务器返回的数据保存在本地的一小块数据(一般小于4kb)。当浏览器发送请求且浏览器存在 Cookie 时,浏览器会自动在请求头携带上 Cookie 数据。引入 Cookie 的意义是因为 HTTP 的请求是无状态的,如:浏览器发出的请求服务器没办法区分浏览器用户身份以及用户的相关操作状态(可以通过 Cookie 传递这些信息)。最开始 Cookie 被作为唯一的存储手段,但是因为浏览器的每次请求都会携带上 Cookie,会带来额外的开销,而且存储量比较小,所以后来浏览器推出了新的 Api(web stoeage Api和 indexedDb)。
二、Cookie 主要使用在以下场景
- 会话状态管理(如用户登录状态、及其他需要记录的信息)
- 个性化设置(如用户自定义设置)
- 浏览器追踪行为(如追踪分析用户行为)
三、创建 Cookie
1.浏览器自动创建
当服务器收到 HTTP 请求时,服务器可以在响应头里设置一个 Set-cookie 选项,浏览器接收到响应后会自动保存下 Cookie,之后浏览器对该服务器的每一次请求中都会通过请求头把 Cookie 信息发送给服务器。通过以下 node 版本代码案例(通过 req.cookie 设置 cookie)当请求了 ‘/’ 路径 Cookie 就会保存如下图信息。后面请求其他 path (如:/login)时在以下代码中都能通过 ‘req.headers.cookie’ 打印出请求携带的 Cookie 信息(即为浏览器保存的 Cookie)。 测试案例(express 版):
const express = require ('express') let app = express(); app.get('/',(req,res)=>{ console.log(req.headers.cookie) res.cookie('token','dsafdsfd453542scdsfd') res.send('path is /') }); app.get('/login',(req,res)=>{ console.log(req.headers.cookie) res.send('path is /login') }); app.listen (3000,()=>{ console.log('express服务已经启动~~~'); })
访问’/’浏览器设置的 Cookie:
2.通过 js 设置 Cookie (也可以设置过期时间、域名、路径等)
注:字符串中不能包含 HttpOnly 标识。可以包含expires、max-age、domain、path、secure。 基本用法:
// 可以直接在浏览器控制台输入进行测试 document.cookie = "token=dsagsdshj43sfs";
四、Cookie 的设置详解
1.过期时间设置(Expires 字段)
设置 Cookie 30s 后过期
// 30s 后浏览器 cookie 自动清空 res.cookie('token','dsafdsfd453542scdsfd',{expires:new Date(Date.now() + 30*1000)})
2.设置域(domain),指定 cookie 在哪个域下可以被接受
注:如果不指定 domain 则默认是当前源(origin),但不包括子域名。如果指定了 Domain 则一般包含子域名(二级域名、三级域名)
res.cookie('token','dsafdsfd453542scdsfd',{domain:'localhost'})
3.设置路径(path),指定 cookie 在当前主机下哪些路径可以接受 Cookie
设置在 /login 下接受 Cookie。(只要是/login开头的都能接受,如:/login/user 等),此时 ‘/’ 下是没有 Cookie 的
res.cookie ('token','dsafdsfd453542scdsfd',{path:'/login'})
4.设置不能通过 javascript 访问 Cookie。(HttpOnly字段)
不能通过 document.cookie 访问
res.cookie('token','dsafdsfd453542scdsfd',{httpOnly:true})
5.设置一段时间过期。(Max-Age)
设置 Cookie 20s 后过期
res.cookie('token','dsafdsfd453542scdsfd',{maxAge:20*1000})
6.设置 secure字段
标记为 secure 的 Cookie 只应通过被 Https 协议加密过的请求发送给服务端。(通过 https 创建的 Cookie 只能通过 Https 请求将 Cookie 携带到服务器,通过 http 无法拿到 Cookie)
res.cookie('token','dsafdsfd453542scdsfd',{secure:true})
7.设置 someSite ,它有三个可选值 None、strict、Lax
首先了解下什么是跨站请求: 比如说有 A、B两个网站,其中A站请求会产生 Cookie,且后续访问请求需携带回 Cookie(身份认证),如果在B网站通过链接的形式访问A站资源这个就叫跨站。这种情况访问成功与否会根据 Cookie 设置的 someSite 而定。 + someSize:None: 浏览器在同站请求、跨站请求下都会发送 Cookies + someSize:Strict: 浏览器只会在相同站点下发送 Cookies + someSize:Lax: 与 strict 类似,不同的是它可以从外站通过链接导航到该站。
五、通过 js 访问 Cookie
注:设置了 HttpOnly 标志的 Cookie 无法访问
document.cookie
六、cookie 分类
会话 Cookie,指的是没有设置 Expires 和 max-Age 标示的 Cookie,关闭浏览器后就会被清空。 包含了 Expire 或 max-Age 的标志,清空的时间由其设置的时间而定。
总结
Cookie 更多的用途是用在身份认证来保证网站资源的安全性,而不是大数据量的本地数据存储。大数据量本地存储方案取而代之的是 webstorage和indexedDB。设置 Cookie 过期时间(Expires、max-Age标志)有助于防止会话固定攻击。设置 httpOnly 有助于缓解跨站点脚本。