误区纠正

  • cookie是浏览器的存储机制,应该和localstorage、sessionStorage、indexedDB、webSQL这种对比
  • session是保存在服务器的一个一组数据(k-v结构),有些网站采取session来用户机制,通常会把sessionID存储在cookie中。此外,session是一个抽象概念,具体实现可以用Redis
  • token和jwt,他们是信息的编码的东西,是信息本身
  • cookie、session、token本质上是不同维度的东西,token也可以存储在cookie中,也可以存储在浏览器的localStorage中
  • cookie是存储在client 的,而session保存在server,sessionId需要借助cookie的传递才有意义

alt text

Cookie、Session、Token有什么区别?

  • 存储位置不同:Cookie存储在客户端,Session存储在服务端、Token存储在客户端(通过加密方式存储在客户端的localStorage和sessionStorage)
  • 数据安全性不同:Cookie存储在客户端,容易被窃取。Session存储在服务器,避免了敏感数据直接暴露,Token通常使用加密算法,单向不可逆,比较安全
  • 跨域支持不同:Cookie不支持跨域,Session通常是用Cookie保存SessionID的,因此也不支持
  • Token支持跨域,因为Token保存在本地的localStorage或者作为请求头的一部分发送到服务端,可以支持跨域
  • 状态管理不同:Cookie是应用程序通过客户端存储临时数据,用于实现状态管理的机制。session是服务器记录用户状态的方式,服务器会为每一个对话分配一个sessionID,关联用户状态。Token是一种用于认证和授权的一种机制,通常表示用户的身份信息和权限信息

为什么有了session还需要token

cookie+session不支持横向扩展,如果请求被负载均衡转发到了别的机器上,没有用户登录信息,就会导致用户请求失败。虽然可以使用redis做分布式session,但是单点故障风险太高,一旦redis崩掉,用户就全部无法访问,而且为了身份验证使用Redis集群不划算
而jwt将用户信息加密为一个字符串传给前端,后端不保存状态,每次都从前端获取状态来实现登录校验

首先请求方输入自己的用户名,密码,然后 server 据此生成 token,客户端拿到 token 后会保存到本地,之后向 server 请求时在请求头带上此 token 即可

token只存储在浏览器中,服务端却没有存储,这样的话我随便搞个token传给server也行?

server会有一套校验机制,校验这个token是否合法

token怎么不像session那样根据 sessionId 找到 userid 呢,这样的话怎么知道是哪个用户?

token本身携带uid信息

如何校验token,或者说JWT如何工作的?

alt text

jwt token有三部分组成:

  • header:签名算法
  • payload:用户id、过期时间等非敏感信息
  • signature:签名,用来验证jwt是否合法

验证流程:
当 server 收到浏览器传过来的 token 时,它会首先取出 token 中的 header+payload,根据服务端的密钥生成签名,然后再与 token 中的签名比对,如果成功则说明签名是合法的,即 token 是合法的

所以jwt就是令牌token,是一个String字符串

基于Redis实现共享session登录?

alt text