Q1/session、cookie、token

Session、Cookie

HTTP是无状态的,为了维护状态,服务器端记录一个会话id(sessionId),记录一下用户及其状态。然后把sessionId回给客户端。浏览器将这个sessionId记录到cookie里,下一次请求再带上。这样服务器从请求中拿到cookie里的sessionId,到自己的存储(一般是用redis)里查一下,得到用户的状态。之后就可以愉快的进行下面的操作了。

session是服务器端的,cookie是浏览器端的
cookie只是实现session的其中一种方案。虽然是最常用的,但并不是唯一的方法。禁用cookie后还有其他方法存储,比如放在url中
现在后端服务都是分布式部署,session一般统一放在redis集群中。这样有个问题就是一旦redis故障,可能会影响所有的用户请求。

所有session都要落地到session服务的存储上,服务压力巨大,任何redis的扩容修改都有可能造成服务端的雪崩。

Cookie

  • 客户端cookie管理存在丢失情况,并且一直难以排查根除,造成用户掉线情况。
  • cookie具有域名特性,业务域名多域名同步存在问题,目前客户端为手动进行同步。
  • cookie的修改,一切api接口客户端均认可,容易发生串号的情况。

Token

那么,我们有没有可能不存储session呢?

  • 如果我们讲所有信息全部放在cookie里,那么只要cookie将用户的id和状态给服务器传过去就好了。
  • 但是,这样非常危险。用户可以随意伪造cookie,并且非常容易被劫持
  • 所以,问题变成了,怎么确保安全性?
  • 答案就是做签名。在用户第一次登录时,服务端使用如SHA256算法对数据进行加密。就称之为token。

下一次浏览器把加密后的token带过来,服务器再使用相同的算法对数据进 行一次加密,比较两次加密的结果,相等即为验证通过。

因为私钥只要服务器知道。所以用户过来的请求是无法伪造的。

这样一来,服务器不需要再费力的保存session数据。服务器端是无状态的。

token的优势:

  • 无状态、可扩展
  • 支持移动设备(移动设备是没有cookie的)
  • 跨程序调用
  • 安全

token认证流程

token 的认证流程与cookie很相似

  • 用户登录,成功后服务器返回Token给客户端。
  • 客户端收到数据后保存在客户端
  • 客户端再次访问服务器,将token放入headers中
  • 服务器端采用filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码

分布式情况下的session和token

我们已经知道session时有状态的,一般存于服务器内存或硬盘中,当服务器采用分布式或集群时,session就会面对负载均衡问题。

  • 负载均衡多服务器的情况,不好确认当前用户是否登录,因为多服务器不共享session。这个问题也可以将session存在一个服务器中来解决,但是就不能完全达到负载均衡的效果。当今的几种解决session负载均衡的方法。

而token是无状态的,token字符串里就保存了所有的用户信息

  • 客户端登陆传递信息给服务端,服务端收到后把用户信息加密(token)传给客户端,客户端将token存放于localStroage等容器中。客户端每次访问都传递token,服务端解密token,就知道这个用户是谁了。通过cpu加解密,服务端就不需要存储session占用存储空间,就很好的解决负载均衡多服务器的问题了。这个方法叫做JWT(Json Web Token)