无状态的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网站是同一家公司的关联服务。现在要求,用户只要在其中一个网站登录,再访问另一个网站就会自动登录,请问怎么实现?这个问题就是如何实现单点登录的问题
- Nginx ip_hash 策略,服务端使用 Nginx 代理,每个请求按访问 IP 的 hash 分配,这样来自同一 IP 固定访问一个后台服务器,避免了在服务器 A 创建 Session,第二次分发到服务器 B 的现象。
- Session复制:任何一个服务器上的 Session 发生改变(增删改),该节点会把这个 Session 的所有内容序列化,然后广播给所有其它节点。
- 共享Session:将Session Id 集中存储到一个地方,所有的机器都来访问这个地方的数据。这种方案的优点是架构清晰,缺点是工程量比较大。另外,持久层万一挂了,就会单点失败;
另一种方案是服务器索性不保存session数据了,所有数据就保存在客户端,每次请求都发回服务器。这种方案就是接下来要介绍的基于Token的验证;
Token
特点
1、无状态、可扩展
2、支持移动设备
3、跨程序调用
4、安全
过程
- 用户通过用户名和密码发送请求
- 程序验证
- 程序返回一个签名的token给客户端
- 客户端储存token, 并且每次请求带上token
- 服务端验证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时间
-
编辑
由于token是无状态的,服务器不需要存储session,使得服务器认证鉴权业务可以方便扩展。这也是JWT最大的缺点由于服务器不需要存储Session状态,因此使用过程中无法废弃某个Token,或者更改Token的权限。也就是说一旦JWT签发了,到期之前就会始终有效。
【问题:当用户修改了密码,而token并未过期或失效咋办?
解决:
- 保存JWT到数据库(或Redis),这样可以针对每个JWT单独校验
- 在重置密码等需要作废之前全部JWT时,把操作时间点记录到数据库(或Redis),校验JWT时同时判断此JWT创建之后有没有过重置密码等类似操作,如果有校验不通过
-
链接
最新SpringBoot实现JWT+延续token过期时间+修改密码失效token -超简单_springboot设置token过期时间_SadPony的博客-CSDN博客
】
参考链接: