HTTP 是一种无状态的协议,无法确保每一次的会话是否为同一个用户发出,浏览器不会保存任何会话信息,所以服务端也就无法确定访问者信息;因此浏览器和服务端会进行一个“会话跟踪”:在进行一些特殊用户权限才有的操作时,将用户状态用Cookie 或 Session 保存起来。
什么是Cookie?
Cookie 是一种主要用于客户端和服务端进行会话验证的凭证。
Cookie 的属性表:
属性 | 类型 | 值 |
---|---|---|
name=value | String | 键值对,字符串类型,用于设置Cookie 的名称和值 |
expires | 符合 HTTP-date 规范的时间戳 | 指定Cookie 的生存期,用于设置Cookie的过期时间 |
max-age | non-zero-digit | 在 cookie 失效之前需要经过的秒数,与expires功能相似 |
domain | 域名String | 指定Cookie 所属的域名,默认为当前域名 |
path | URL 路径 | 指定 cookie 在哪个路径(路由)下生效,默认是 '/' |
参考 Set-Cookie
Cookie 的创建方式:
第一种是客户端通过 js 设置,举个栗子:用一个 js-cookies
库,已封装好 document.cookie 的方法
import Cookies from 'js-cookie'
Cookies.set('name', 'value', { expires: 7, path: '' }); //7天过期
Cookies.set('name', { foo: 'bar' }); //设置一个json
第二种是服务端通过在 HTTP 响应头 设置 Set-Cookie
, 举个栗子:

需要注意的是,在域名相同(端口号不同的跨域)的情况下,Cookie是可以共享的,而其他跨域情况则无法获取。
什么是Session?
Session 是基于Cookie 实现的另一种记录服务端和客户端会话状态的机制。
Session 是存储在服务端,而 SessionId 会被存储在客户端的 Cookie 中。
Session 的认证过程:
- 客户端第一次发送请求到服务端,服务端根据信息创建对应的 Session, 并在响应头返回 SessionID (也就是Set-Cookie)
- 客户端接收到服务端返回的 SessionID 后,会将此信息存储在 Cookie 上,同时会记录这个 SessionID 属于哪个域名
- 当客户端再次访问服务端时,请求会自动判断该域名下是否存在 Cookie 信息,如果有则发送给服务端,服务端会从 Cookie 中拿到 SessionID,再根据 SessionID 找到对应的 Session, 如果有对应的 Session 则通过,继续执行请求,否则就中断。


Cookie 和 Session 的区别?
- 安全性。因为 Cookie 可以通过客户端修改,而 Session 只能在服务端设置,所以安全性比 Cookie 高,一般会用于验证用户登录状态
- 适用性。Cookie 只能存储字符串数据,而 Session 可以存储任意类型数据
- 有效期。Cookie 可以设置任意时间有效,而 Session 一般失效时间短
- 继承性。一般客户端设置 Cookie,如果要用于验证就需要服务端创建 Session
Token又是什么?
Token 是访问资源接口(API)时所需要的资源凭证。与 Session 相比,token的优点是不需要存储数据在服务端,服务端只需要根据客户端传来的 token 进行合法验证,通过后则返回请求资源即可,减轻了服务端的资源占用压力. 目前最流行的跨域认证解决方案 JWT (JSON WEB TOKEN) 就是基于 token 实现。 以下就以 JWT 标准介绍Token
JWT 的认证流程:
- 客户端发送用户信息给服务端请求登录
- 服务端验证用户信息,验证通过后签发一个 Token 返回给客户端,客户端收到后会存储在 Cookie 或 localStorage 中
- 客户端继续第二次业务请求,请求头的 Authorization 字段携带这个 Token或者直接放在 Cookie(但是这样就不能跨域了)
- 服务端根据 headers 中的 Token 进行验证,验证通过后返回业务请求的数据

JWT 的优点:
- 可用于应用管理,避开同源策略
- 避免 CSRF 攻击
- 实现无状态服务端,能够在多个服务间使用,可扩展性好
参考
一文彻底搞懂Cookie、Session、Token到底是什么