session、cookie、token的区别

未分类3天前更新 geekmao
12 0 0

1 、概述

我们都知道 HTTP 协议是无状态的,所谓的无状态就是客户端每次想要与服务端通信,都必须重新与服务端链接,意味着请求一次客户端和服务端就连接一次,下一次请求与上一次请求是没有关系的。

这种无状态的方式就会存在一个问题:如何判断两次请求的是同一个人?就好比用户在页面 A 发起请求获取个人信息,然后在另一个页面同样发起请求获取个人信息,我们如何确定这俩个请求是同一个人发的呢?

为了解决这种问题,我们就迫切需要一种方式知道发起请求的客户端是谁?此时,cookietokensession 就出现了,它们就可以解决客户端标识的问题,在扩大一点就是解决权限问题。

它们就好比让每个客户端或者说登录用户有了自己的身份证,我们可以通过这个身份证确定发请求的是谁。

2、什么是cookie

2.1 概念

Cookie 是一种在客户端存储数据的技术,它是由服务器发送给客户端的小型文本文件,存储在客户端的浏览器中,大小限制大致在 4KB 左右。在客户端发送请求时,浏览器会自动将相应的 Cookie 信息发送给服务器,服务器通过读取 Cookie 信息,就可以判断该请求来自哪个客户端。Cookie 可以用于存储用户的登录状态、购物车信息等。

在以前很多开发人员通常用 cookie 来存储各种数据,后来随着更多浏览器存储方案的出现,cookie 存储数据这种方式逐渐被取代,主要原因有如下:

  1. cookie 有存储大小限制,4KB 左右。
  2. 浏览器每次请求会携带 cookie 在请求头中。
  3. 字符编码为 Unicode,不支持直接存储中文。
  4. 数据可以被轻易查看。

2.2 cookie 的主要属性

属性名 描述
name cookie 的名称
value cookie 的值
comment cookie 的描述信息
domain 可以访问该 cookie 的域名
expires cookie 的过期时间,具体某一时间
maxAge cookie 的过期时间
path cookie 的使用路径
secure cookie 是否使用安全协议传输,比如 SSL 等
version cookie 使用的版本号
isHttpOnly 指定该 Cookie 无法通过 JavaScript 脚本拿到,比如 Document.cookie 属性、XMLHttpRequest 对象和 Request API 都拿不到该属性。这样就防止了该 Cookie 被脚本读到,只有浏览器发出 HTTP 请求时,才会带上该 Cookie。


2.3 使用流程

那么我们是如何通过 cookie 来实现用户确定或者权限的确定呢?看下图:

session、cookie、token的区别

接下来说说大体流程

  1. 客户端发送请求到服务端(比如登录请求)。
  2. 服务端收到请求后生成一个 session 会话。
  3. 服务端响应客户端,并在响应头中设置 Set-Cookie。Set-Cookie 里面包含了 sessionId,它的格式如下:Set-Cookie: value [; expires=date] [; domain=domain] [; path=path] [; secure] 。其中 sessionId 就是用来标识客户端的,类似于去饭店里面,服务员给你一个号牌,后续上菜通过这个号牌来判断上菜到哪里。
  4. 客户端收到该请求后,如果服务器给了 Set-Cookie,那么下次浏览器就会在请求头中自动携带 cookie。
  5. 客户端发送其它请求,自动携带了 cookie,cookie 中携带有用户信息等。
  6. 服务端接收到请求,验证 cookie 信息,比如通过 sessionId 来判断是否存在会话,存在则正常响应。

2.4 cookie 主要特点

  1. cookie 存储在客户端
  2. cookie 不可跨域,但是在如果设置了 domain,那么它们是可以在一级域名和二级域名之间共享的。

3、什么是 session

3.1 概念

session 由服务端创建,当一个请求发送到服务端时,服务器会检索该请求里面有没有包含 sessionId 标识,如果包含了 sessionId,则代表服务端已经和客户端创建过 session,然后就通过这个 sessionId 去查找真正的 session,如果没找到,则为客户端创建一个新的 session,并生成一个新的 sessionId 与 session 对应,然后在响应的时候将 sessionId 给客户端,通常是存储在 cookie 中。如果在请求中找到了真正的 session,验证通过,正常处理该请求。

每一个客户端与服务端连接,服务端都会为该客户端创建一个 session,并将 session 的唯一标识 sessionId 通过设置 Set-Cookie 头的方式响应给客户端,客户端将 sessionId 存到 cookie 中。

3.2 流程图

通常情况下,cookie 和 session 都是结合着来用,当然你也可以单独只使用 cookie 或者单独只使用 session,这里我们就将 cookie 和 session 结合着来用。如下图,具体流程介绍看上面cookie流程即可。

session、cookie、token的区别

3.3 与 cookie 的区别

cookie 和 session,它们两者之间主要是通过 sessionId 关联起来的,所以总结出:sessionId 是 cookie 和 session 之间的桥梁。

session 是基于 cookie 实现的,它们两个主要有以下特点:

  1. session 比 cookie 更加安全,因为它是存在服务端的,cookie 是存在客户端的。
  2. cookie 只支持存储字符串数据,session 可以存储任意数据。
  3. cookie 的有效期可以设置较长时间,session 有效期都比较短。
  4. session 存储空间很大,cookie 有限制。

系统想要实现鉴权,可以单独使用 cookie,也可以单独使用 session,但是建议结合两者使用。

4、token 是什么

4.1 概念

Token 是一种在客户端和服务端之间传递身份信息的方式。当用户登录成功后,服务端会生成一个 Token,将其发送给客户端。客户端在后续的请求中,需要将 Token 携带在请求头或请求参数中。服务端通过验证 Token 的合法性,就可以确定该请求来自哪个用户,并且可以根据用户的权限进行相应的操作。Token 可以有效地避免了 Cookie 的一些安全问题,比如 CSRF 攻击。

4.2 token 的组成

Token是一个由一串字符组成的令牌,用于在计算机系统中进行身份验证和授权。它通常由三个部分组成:标头、有效载荷、签名。

  1. 标头( Header ):包含了算法和类型,用于指定如何对有效载荷进行编码和签名。常用的算法有HMAC、RSA、SHA等。
  2. 有效载荷( Payload ):包含了一些信息,如用户ID、角色、权限等,用于验证身份和授权。有效载荷可以是加密的,也可以是明文的。
  3. 签名( Signature ):是对标头和有效载荷进行签名后得到的值,用于验证 token 的完整性和真实性。签名通常使用私钥进行签名,并使用公钥进行验证。

一个完整的 token 包含了标头、有效载荷和签名三个部分,它们一起构成了一个安全的令牌,用于进行身份验证和授权。

4.3 token 认证流程

  1. 客户端发起登录请求,比如用户输入用户名和密码后登录。
  2. 服务端校验用户名和密码后,将用户 id 和一些其它信息进行加密,生成 token。
  3. 服务端将 token 响应给客户端。
  4. 客户端收到响应后将 token 存储下来。
  5. 下一次发送请求后需要将 token 携带上,比如放在请求头中或者其它地方。
  6. 服务端 token 后校验,校验通过则正常返回数据。

看下图:

session、cookie、token的区别

5、三者对比

cookie、session、token 三者最终的目的都是一样:鉴权和认证,下面使用表格的方式直观的描述下三者的优缺点。

方式 特点 优点 缺点
cookie 1、存储在客户端。
2、请求自动携带 cookie。
3、存储大小 4KB。
1、兼容性好,因为是比较老的技术。
2、很容易实现,因为 cookie 会自动携带和存储。
1、需要单独解决跨域携带问题,比如多台服务器如何共享 cookie。
2、会遭受 CSRF 攻击。
3、存储在客户端,不够安全。
session 1、存储在服务端。
2、存储大小无限制。
1、查询速度快,因为是个会话,相当于是在内存中操作。
2、结合 cookie 后很容易实现鉴权。
3、安全,因为存储在服务端。
1、耗费服务器资源,因为每个客户端都会创建 session。
2、占据存储空间,session 相当于存储了一个完整的用户信息。
token 1、体积很小。
2、自由操作存储在哪里。
1、安全,因为 token 一般只有用户 id,就算被截取了也没什么用。
2、无需消耗服务器内存资源,它相当于只存了用户 id,session 相当于存储了用户的所有信息。
3、跨域处理较为方便,比如多台服务器之间可以共用一个 token。
1、查询速度慢,因为 token 只存了用户 id,每次需要去查询数据库。

PS:总结下来就是session 是空间换时间,token 是时间换空间。

© 版权声明

相关文章

暂无评论

暂无评论...