Cookie, Session, Token 对比
Cookie
Cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。
**Cookie 由服务器生成,发送给浏览器,浏览器把 Cookie 以 K/V 形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该 Cookie 发送给服务器。**由于 Cookie 是存在客户端上的,所以浏览器加入了一些限制确保 Cookie 不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的 Cookie 数量是有限的。
Session
Session 从字面上讲,就是会话。这个就类似于你和一个人交谈,你怎么知道当前和你交谈的是张三而不是李四呢?对方肯定有某种特征(长相等)表明他就是张三。
Session 也是类似的道理,服务器要知道当前发请求给自己的是谁。为了做这种区分,**服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。**至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大家都默认采用 Cookie 的方式。
服务器使用 Session 把用户的信息临时保存在了服务器上,用户离开网站后 Session 会被销毁。这种用户信息存储方式相对 Cookie 来说更安全,可是 Session 有一个缺陷:如果 Web 服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候 Session 会丢失。
Token
Token 的引入:Token 是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token 便应运而生。
Token 的定义:Token 是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个 Token 便将此 Token 返回给客户端,以后客户端只需带上这个 Token 前来请求数据即可,无需再次带上用户名和密码。最简单的 Token 组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,由 Token 的前几位 + 盐以哈希算法压缩成一定长的十六进制字符串,可以防止恶意第三方拼接 Token 请求服务器)。
传统身份验证
HTTP 是一种没有状态的协议,也就是它并不知道是谁是访问应用。这里我们把用户看成是客户端,客户端使用用户名还有密码通过了身份验证,不过下回这个客户端再发送请求时候,还得再验证一下。
解决的方法就是,当用户请求登录的时候,如果没有问题,我们在服务端生成一条记录,这个记录里可以说明一下登录的用户是谁,然后把这条记录的 ID 号发送给客户端,客户端收到以后把这个 ID 号存储在 Cookie 里,下次这个用户再向服务端发送请求的时候,可以带着这个 Cookie ,这样服务端会验证一个这个 Cookie 里的信息,看看能不能在服务端这里找到对应的记录,如果可以,说明用户已经通过了身份验证,就把用户请求的数据返回给客户端。
上面说的就是 Session,我们需要在服务端存储为登录的用户生成的 Session,这些 Session 可能会存储在内存,磁盘,或者数据库里。我们可能需要在服务端定期的去清理过期的 Session。
基于 Token 的身份验证
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
- 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据