cookie
# cookie
- cookie就是用来解决状态管理的问题。
- HTTP协议是一个无状态的协议,从而导致服务器接收客户端的请求,返回一个响应,如果没有记录关于客户端的任何信息,那么等下次客户端再次发起请求的时候,服务器并不知道客户端是谁。
- 而cookie是存储在浏览器的一个小小文本文件,可以附着在HTTP请求上,在浏览器和服务器之间飞来飞去,可以携带用户信息。
一个请求首部,其中含有先前由服务器通过 Set-Cookie 首部投放并存储到客户端的 HTTP cookies。(字符串信息)
这个首部可能会被完全移除,例如在浏览器的隐私设置里面设置为禁用cookie。
查看:Application->Storage->Cookies
[TOC]
# 一、cookie特性
# 1.1 前端数据存储
# 1.1.1 cookie的有效期
- Expires
- 俗称过期时间,可以理解成截止日期,用的是绝对时间。
- 默认一个cookie的生命周期就是在关闭浏览器的时候结束。
- Max-Age(优先级较Expires高)
- 相对时间,单位是秒。
- 兼容问题:
- Chrome:
new Date()
->GMT时间(北京标准时间GMT+0800) IE:new Date()
->UTC时间(北京标准时间UTC+0800) - Chrome:cookie的过期时间->GMT时间 IE和FF:cookie的过期时间->本地时间写入cookie的过期时间 查看chrome的cookie有效期时默认加8小时
- UTC:根据原子钟来计算时间,50亿年误差一秒 GMT:根据地球的自转和公转来计算时间
- Chrome:
# 1.1.2 cookie的作用域
让浏览器仅发送给特定的服务器和URI,避免被其他网站盗用。
- Domian:指定cookie所属的域名。
- Path:指定cookie所属的路径。
- 现实中为了省事,通常Path就用一个“/”或者直接省略,表示域名下的任意路径都允许使用cookie,让服务器自己去挑。
# 1.1.3 cookie的安全性
- HttpOnly
- 表明此cookie只能通过浏览器HTTP协议传输,禁止其他方式访问。浏览器的JS引擎就会禁用document.cookie等一切相关API,脚本攻击也就无从谈起了。
- SameSite
- 可以防范CSRF。
- 设置成“SameSite=Strict”可以严格限定Cookie不能随着跳转链接跨站发送,而“SameSite=Lax"则略宽松一点,允许GET/HEAD等安全方法,但禁止POST跨贴发送。
- Secure
- 表示Cookie仅能用HTTPS协议加密传输,明文的HTTP协议会禁止发送。但Cookie本身不是加密,浏览器里还是以明文的形式存在。
# 1.2 前端可读写
- 服务端向客户端发送cookie
Set-Cookie: <cookie-name>=<cookie-value>;(可选参数1);(可选参数2)
- 客户端设置cookie
document.cookie = "<cookie-name>=<cookie-value>;(可选参数1);(可选参数2)"
# 1.3 遵守同源策略
可以通过特殊设置达到cookie跨域访问
# 二、cookie类型
- 当前网站本身设置的cookie
- 其他域来源的第三方cookie:跟踪你的使用信息
# 三、大小限制
- 每个cookie所存放的数据不能超过4k。
- 如果cookie字符串长度超过4k,则该属性将返回空字符串。
# 四、cookie 作用
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
# 4.1 身份识别
存储个性化设置
- 选择了怎样的皮肤
- 上次停留的页面
- 一个菜单是打开还是关闭
存储未登录时用户唯一标识
- 生成随机的标识区分你是你,我是我
存储已登录用户的凭证
过程:
- 前端提交用户名和密码
- 后端验证用户名和密码
- 后端通过http头设置用户凭证
- 后续访问时后端先验证用户凭证
方法:
用户ID:给用户发一个号
- 存在巨大的安全隐患:
userId=1
用户通过纂改document.cookie="userId=2"
模拟用户2登录
- 存在巨大的安全隐患:
用户ID+签名:
- 签名是不伪造的,只有后台才知道密钥
- 通过用户ID去验证签名是否一致,可防止篡改
- 可能被盗取
SessionId:
- 并不存放真正的数据,存放的数据与用户无关
- 随机的字符串,防篡改防盗取,只给前端一个随机字符串标识
//session.js var session = {}; var cache = {}; session.set = function(userId, obj) { var sessionId = Math.random(); if (!cache[sessionId]) { cache[sessionId] = {}; } cache[sessionId].content = obj; }; session.get = function(sessionId) { return cache[sessionId] && cache[sessionId].content; };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16Token
存储业务其他数据
- 根据具体需求缓存数据
# 4.2 广告跟踪
这种cookie不是由访问的主站存储的,而是由广告图片背后的广告商给你贴上cookie小纸条,以方便精准打击,所以也叫第三方cookie(third-party)。
# 五、安全问题
# 5.1 cookie与XSS
- XSS可能偷取cookie:可以用js的
document.cookie
访问cookie- http-only的cookie不会被偷
# 5.2 cookies与CSRF
- CSRF利用了用户Cookies:目标网站会带上用户的cookie
- 攻击站点无法读写cookies
- 最好能阻止第三方使用cookie:验证码
- 攻击站点无法读写cookies
# 5.3 cookie安全策略
- 签名防篡改
- 私有变换(加密):用户不知道值代表的含义
- http-only防XSS
- secure防传输过程中的监听
- same-site防CSRF
# 六、session
参考教程:你真的了解 Cookie 和 Session 吗 (opens new window)
# 6.1 什么是session
- Session 代表着服务器和客户端一次会话的过程。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者 Session 超时失效时会话结束。
- 当访问增多时,
Session
会较大地占用服务器的性能。考虑到减轻服务器性能方面,应当适时使用Cookie
。 Session
的运行依赖Session ID
,而Session ID
是存在 Cookie 中的。也就是说,如果浏览器禁用了Cookie
,Session
也会失效(但是可以通过其它方式实现,比如在url
中传递Session ID
,即sid=xxxx)。- session保存在服务器,客户端不知道其中的信息。
# 6.2 cookie与session的不同
cookie | session | |
---|---|---|
作用范围 | 保存在浏览器 | 保存在服务器 |
存储类型 | 只能保存 ASCII | 任意数据类型 |
有效期 | 较长,比如用于默认登录功能 | 较短,浏览器关闭或超时就失效 |
安全性 | 低 | 高 |
存储大小 | 4k | 远高于4k |
# 6.3 cookie和session的由来
浏览器是没有状态的(HTTP 协议无状态),这意味着浏览器并不知道是张三还是李四在和服务端打交道。这个时候就需要有一个机制来告诉服务端,本次操作用户是否登录,是哪个用户在执行的操作,那这套机制的实现就需要 Cookie 和 Session 的配合。
- SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。
# 6.4 禁用cookie
既然服务端是根据 Cookie 中的信息判断用户是否登录,那么如果浏览器中禁止了 Cookie,如何保障整个机制的正常运转。
# 6.4.1 SessionID
每次请求中都携带一个 SessionID 的参数,也可以 Post 的方式提交,也可以在请求的地址后面拼接 xxx?SessionID=123456...
。
# 6.4.2 Token机制
参考教程:干掉状态:从session到token (opens new window)
Token 机制多用于 App 客户端和服务器交互的模式,也可以用于 Web 端做用户状态管理。
Token 的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。Token 机制和 Cookie 和 Session 的使用机制比较类似。
当用户第一次登录后,服务器根据提交的用户信息生成一个 Token,响应时将 Token 返回给客户端,以后客户端只需带上这个 Token 前来请求数据即可,无需再次登录验证。
- 服务器不用保存sessionId,只用生成token,然后验证token,用CPU的计算时间来获取session的存储空间。
- 机器集群可以轻松地做水平扩展,用户访问量增大,直接加机器就行了。