cookie 与 session的应用场景

1,303 阅读3分钟

Cookie 和 Session 都是用来跟踪浏览器用户身份的会话方式,但是两者的应用场景不太一样。 Cookie 一般用来保存用户信息 我们在 Cookie 中保存已经登录过得用户信息,下次访问网站的时候页面可以自动帮你登录的一些基本信息给填了

一般的网站都会有保持登录也就是说下次你再访问网站的时候就不需要重新登录了,这是因为用户登录的时候我们可以存放了一个 Token 在 Cookie 中,下次登录的时候只需要根据 Token 值来查找用户即可(为了安全考虑,重新登录一般要将 Token 重写);

登录一次网站后访问网站其他页面不需要重新登录。Session 的主要作用就是通过服务端记录用户的状态。 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为 HTTP 协议是无状态的。服务端给特定的用户创建特定的 Session 之后就可以标识这个用户并且跟踪这个用户了。

Cookie 数据保存在客户端(浏览器端),Session 数据保存在服务器端。 Cookie 存储在客户端中,而 Session 存储在服务器上,相对来说 Session 安全性更高。如果要在 Cookie 中存储一些敏感信息,不要直接写入 Cookie 中,最好能将 Cookie 信息加密然后使用到的时候再去服务器端解密。

#Cookie

服务器端返回数据的时候通过 Set-Cookie 设置 Header,设置到浏览器中;浏览器保存了这个 Cookie 之后,在下次请求的时候(同域)会携带这个 Cookie,来保证记录用户状态(因为 Http 是无状态的);如果在请求头中没有设置 Cookie 的过期时间,默认是浏览器关闭后 Cookie 就会清空。

#属性

max-age 和 expires 设置过期时间(expires 是在哪个时间点过期,max-age 是多长时间) Secure 只在 https 的时候发送 HttpOnly 无法通过 document.cookie 访问 #node 实践

#设置 Cookie

const http =require('http')const fs =require('fs')http.createServer(function(req, res){if(req.url ==='/'){const html = fs.readFileSync('test.html','utf-8') res.writeHead(200,{'Content-Type':'text/html','Set-Cookie':'id=123'// 可以设置多个 Cookie'Set-Cookie':['id=123','abc=456']}) res.end(html)}}).listen(8888)

document.cookie 得到的结果:id=123; abc=456 注意分号后面有一个空格。

#设置过期时间

设置过期时间:下面设置了 id=123 这个值过期时间是两秒。如果我们第一次请求完之后,等待两秒后再次发送请求,会发现请求中携带的 cookie 中只有 abc=456; id=123 过期了。

const http =require('http')const fs =require('fs')http.createServer(function(req, res){if(req.url ==='/'){const html = fs.readFileSync('test.html','utf-8') res.writeHead(200,{'Content-Type':'text/html','Set-Cookie':['id=123; max-age=2','abc=456']}) res.end(html)}}).listen(8888)

#设置 HttpOnly

const http =require('http')const fs =require('fs')http.createServer(function(req, res){if(req.url ==='/'){const html = fs.readFileSync('test.html','utf-8') res.writeHead(200,{'Content-Type':'text/html','Set-Cookie':['id=123; max-age=2','abc=456; HttpOnly']}) res.end(html)}}).listen(8888)

在浏览器中使用 document.cookie 是获取不到 abc=456 的值。

#设置 Domain

在同一个主域名下的二级域名可以共享 Cookie,比如主域名 test.com 有两个二级域名 a.test.com 和 b.test.com 两个:

const http =require('http')const fs =require('fs')http.createServer(function(req, res){const host = req.headers.host if(req.url ==='/'){const html = fs.readFileSync('test.html','utf-8')if(host ==='test.com'){ res.writeHead(200,{'Content-Type':'text/html','Set-Cookie':['id=123; max-age=2','abc=456; domain=test.com']})} res.end(html)}}).listen(8888)