Cookie
什么是 Cookie
在服务端返回数据时,通过设置 Set-Cookie 头到浏览器中,并保存到浏览器的内容,这个内容就是 Cookie。
浏览器保存 Cookie 之后,在下次同域的请求当中,就会带上这个 Cookie,实现用户访问网站的会话当中的数据是一致的。可以设置多个 Cookie,以键值对的方式保存在浏览器。
通过 Set-Cookie设置
下次请求会自动带上
键值对,可以设置多个
Cookie 属性
max-age 和 expires 设置过期时间
Secure 只在 https 的时候发送
HttpOnly 无法通过 document.cookie 访问,基于安全性考虑,如 csrf 攻击,通过在用户网页注入脚本或 url,引导用户给攻击者的服务器发送用户使用网站的 Cookie,攻击者拿到用户登录状态,并利用 Cookie 访问网站保存的用户数据。所以禁止重要数据通过 JS 进行访问,是保证用户数据安全非常重要的一步。
Cookie 的使用
通过 JS 访问 Cookie 的内容
命令行 node server.js 启动服务器,8888端口打开网页。
服务器通过 Set-Cookie 设置 Cookie 的值。
控制台->application->Cookies,可以看到 Cookie 的信息。
network查看,localhost 文件请求头中有 Cookie,响应头中也有 Cookie,因为每次服务器都会下发。
通过 JS,document.cookie 可以拿到 Cookie 的值 123。
// server.jsconst http = require('http')const fs = require('fs')http.createServer(function (request, response) { console.log('request come', request.url) if (request.url === '/') { const html = fs.readFileSync('test.html', 'utf8') response.writeHead(200, { 'Content-Type': 'text/html', 'Set-Cookie': '123' // 通过 Set-Cookie 设置 cookie 值 }) response.end(html) }}).listen(8888)console.log('server listening on 8888')复制代码
// test.html复制代码
返回多个 Cookie
在 network 中,localhost 文件的响应头中有两个 Set-Cookie头,说明服务器下发了多个 Cookie,并且在 Response Headers 中是可以重复的。
在 application 的 Cookies 中 可以看到两条 cookie 数据。
'Set-Cookie': ['123','abc=456'] // nodejs中通过数组的形式设置多个 Cookie复制代码
Cookie 时效
Cookie 有时效性。
如果没有设置过期时间,当浏览器关闭之后,Cookie 消失。第一次访问时,查看 network发现并没有 Cookie,刷新后会带上 Cookie。application 中是有数据的,这个是浏览器下发的。
设置 Cookie 过期时间
通过 max-age 设置过期时间
'Set-Cookie': ['id=123;max-age=2','abc=456'] // 设置 id=123 的过期时间是 2s复制代码
刷新页面,network 中 localhost
Request Headers Set-Cookie: id=123;max-age=2 Set-Cookie: abc=456Request Headers Cookie: id=123; abc=456复制代码
超过2s,再次刷新页面
Request Headers Set-Cookie: id=123;max-age=2 Set-Cookie: abc=456Request Headers Cookie: abc=456 // 123 过期了,所以请求不会带上复制代码
超过过期时间的 Cookie,浏览器发送请求时就不会带上了。
max-age 和 expires 是两种不同的写法,效果一样。expires 是到什么时间点过期。max-age 计算简单。
禁止 JS 访问 Cookie
通过 HttpOnly 禁止 JS 访问 Cookie。
开发过程中,如果涉及到安全性问题,可以考虑禁用。
'Set-Cookie': ['id=123;max-age=2','abc=456; HttpOnly'] // 给 abc=456 的 cookie 设置禁止 JS 访问复制代码
// test.html复制代码
二级域名访问一级域名的 Cookie
通过 Cookie 的 domain 设置
Cookie 有访问域的权限设定,一般情况下,当前要访问的 Cookie 其他域是不能访问的,如 下的 Cookie,只有在 的域名下才能访问到, 就不能访问。
对于同一个域名,Cookie 有更多的限制方案。 有二级域名 ,可以让 访问到 下的 Cookie,通过 domain 的方式实现。
和 在系统的 host 中映射成 locahost,通过 HostAdmin App 完成映射。把两个域名映射到 127.0.0.1
hosts文件无法更改解决方案,。
这样通过 和 b.test.com:8888可以进行访问了。
在 application 的 Cookies 下 可以看到 Cookie。
在 application 的 Cookies 下 看不到 Cookie,因为服务端没有设置。
如何让二级域名都能访问到一级域名下的 Cookie 呢
通过 domain 来设置
// server.jsconst http = require('http')const fs = require('fs')http.createServer(function (request, response) { console.log('request come', request.url) const host = request.headers.host if (request.url === '/') { const html = fs.readFileSync('test.html', 'utf8') if (host === 'test.com:8888') { // 注意这里是一级域名 response.writeHead(200, { 'Content-Type': 'text/html', 'Set-Cookie': ['id=123','abc=456;domain=test.com'] // 给 abc=456 设置 domain }) } response.end(html) }}).listen(8888)console.log('server listening on 8888')复制代码
访问一级域名 可以看到两个 Cookie。
访问二级域名 可以看到 abc=456 的 Cookie ,并且每次请求都会带上。
Session
session 有很多种实现方法,在网站当中最经常用的是使用 Cookie 来保存 session。
把用户登录后的 Id 或者 session 的 key 设置到 Cookie 中,每个用户对应的值都不一样,当用户再次请求,服务端读取 Cookie 中的值,通过这个值拿到用户对应的唯一的 key,通过 key 来定位用户的信息,并做一系列的操作。
把用户 id 相关信息转化成对应的唯一 key,用户信息和 session key 的对应关系存在服务端的数据库或者缓存中。
请求时,服务端读取 session key ,再对应找到对应用户信息。