cookie、session、Token

无状态的HTTP协议

接口一般是通过 HTTP 协议来进行数据交换的,而 HTTP 协议的特点是,无状态,工作前通过三次握手建立连接,工作完成后立刻通过四次挥手断开连接, 每次请求都是一个新的HTTP协议,就是请求加响应。不用记录谁刚刚发了HTTP请求, 每次请求都是全新的。即耗费了性能,也给黑客的攻击留下隐患。

cookie

cookie由服务器生成,发送给浏览器,浏览器把cookie以KV形式存储到某个目录下的文本文件中,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间。所以每个域的cookie数量是有限制的

session

session是服务器给客户端分配的身份验证的表识。然后客户端每次向服务器发请求的时候,都带上这个”身份标识“,服务器就知道这个请求来自与谁了。 至于客户端怎么保存这个”身份标识“,可以有很多方式,对于浏览器客户端,大家都采用cookie的方式。

过程(服务端session + 客户端 sessionId)

  • 1.用户向服务器发送用户名和密码
  • 2.服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色, 登陆时间等;
  • 3.服务器向用户返回一个session_id, 写入用户的cookie
  • 4.用户随后的每一次请求, 都会通过cookie, 将session_id传回服务器
  • 5.服务端收到 session_id, 找到前期保存的数据, 由此得知用户的身份

存在的问题

扩展性不好

单机当然没问题, 如果是服务器集群, 或者是跨域的服务导向架构, 这就要求session数据共享,每台服务器都能够读取session。

举例来说, A网站和B网站是同一家公司的关联服务。现在要求,用户只要在其中一个网站登录,再访问另一个网站就会自动登录,请问怎么实现?这个问题就是如何实现单点登录的问题

  1. Nginx ip_hash 策略,服务端使用 Nginx 代理,每个请求按访问 IP 的 hash 分配,这样来自同一 IP 固定访问一个后台服务器,避免了在服务器 A 创建 Session,第二次分发到服务器 B 的现象。
  2. Session复制:任何一个服务器上的 Session 发生改变(增删改),该节点会把这个 Session 的所有内容序列化,然后广播给所有其它节点。
  3. 共享Session:将Session Id 集中存储到一个地方,所有的机器都来访问这个地方的数据。这种方案的优点是架构清晰,缺点是工程量比较大。另外,持久层万一挂了,就会单点失败;

另一种方案是服务器索性不保存session数据了,所有数据就保存在客户端,每次请求都发回服务器。这种方案就是接下来要介绍的基于Token的验证;

Token

特点

1、无状态、可扩展

2、支持移动设备

3、跨程序调用

4、安全

过程

 

  1. 用户通过用户名和密码发送请求
  2. 程序验证
  3. 程序返回一个签名的token给客户端
  4. 客户端储存token, 并且每次请求带上token
  5. 服务端验证Token并返回数据

这个方式的技术其实很早就已经有很多实现了,而且还有现成的标准可用,这个标准就是JWT;

JWT(JSON Web Token)

数据结构

实际的JWT大概就像下面这样:

 

JSON Web Tokens由dot(.)分隔的三个部分组成,它们是:

  • Header(头部)【Header 是一个 JSON 对象】
  • Payload(负载)【Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。】
  • Signature(签名)【Signature 是对前两部分的签名,防止数据被篡改。】

因此,JWT通常如下展示:

xxxxx.yyyyy.zzzz

如何保证安全?

  • 发送JWT要使用HTTPS;不使用HTTPS发送的时候,JWT里不要写入秘密数据
  • JWT的payload中要设置expire时间
  • wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== 编辑

由于token是无状态的,服务器不需要存储session,使得服务器认证鉴权业务可以方便扩展。这也是JWT最大的缺点由于服务器不需要存储Session状态,因此使用过程中无法废弃某个Token,或者更改Token的权限。也就是说一旦JWT签发了,到期之前就会始终有效。 

【问题:当用户修改了密码,而token并未过期或失效咋办?

    解决:

  1. 保存JWT到数据库(或Redis),这样可以针对每个JWT单独校验
  2. 在重置密码等需要作废之前全部JWT时,把操作时间点记录到数据库(或Redis),校验JWT时同时判断此JWT创建之后有没有过重置密码等类似操作,如果有校验不通过
  3.  链接

    最新SpringBoot实现JWT+延续token过期时间+修改密码失效token -超简单_springboot设置token过期时间_SadPony的博客-CSDN博客

参考链接:

详解 Cookie,Session,Token - 掘金

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值