一文秒懂JWT实现无状态登录

⽆状态登录原理

在讲解无状态登录的前提下,我们先了解一下什么是有状态登录?

什么是有状态?

有状态服务,即服务端需要记录每次会话的客户端信息,从⽽识别客户端身份,根据⽤户身份进⾏请求的处理,典型的设计如tomcat中session。

例如登录:⽤户登录后,我们把登录者的信息保存在服务端session中,并且给⽤户⼀个cookie值,记录对应的session。然后下次请求,⽤户携带cookie值来,我们就能识别到对应session,从⽽找到⽤户的信息。

缺点是什么?

  • 服务端保存⼤量数据,增加服务端压⼒
  • 服务端保存⽤户状态,⽆法进⾏⽔平扩展
  • 客户端请求依赖服务端,多次请求必须访问同⼀台服务器

什么是⽆状态

微服务集群中的每个服务,对外提供的都是Rest⻛格的接⼝。⽽Rest⻛格的⼀个最重要的规范就是:

服务的⽆状态性,即:

  • 服务端不保存任何客户端请求者信息
  • 客户端的每次请求必须具备⾃描述信息,通过这些信息识别客户端身份带来的好处是什么呢?
  • 客户端请求不依赖服务端的信息,任何多次请求不需要必须访问到同⼀台服务
  • 服务端的集群和状态对客户端透明
  • 服务端可以任意的迁移和伸缩
  • 减⼩服务端存储压⼒

如何实现⽆状态

⽆状态登录的流程:

  • 当客户端第⼀次请求服务时,服务端对⽤户进⾏信息认证(登录)
  • 认证通过,将⽤户信息进⾏加密形成token,返回给客户端,作为登录凭证
  • 以后每次请求,客户端都携带认证的token服务端对token进⾏解密,判断是否有效。
  • 服务端对token进⾏解密,判断是否有效。

流程图如下:

一文秒懂JWT实现无状态登录_第1张图片
image.png

整个登录过程中,最关键的点是什么?
token的安全性
token是识别客户端身份的唯⼀标示,如果加密不够严密,被⼈伪造那就完蛋了。
采⽤何种⽅式加密才是安全可靠的呢?
我们将采⽤ JWT + RSA⾮对称加密

下面我们就针对上面的问题引入JWT,看一下JWT是如果解决上面token的安全性的问题的。

JWT简介

JWT,全称是Json Web Token, 是JSON⻛格轻量级的授权和身份认证规范,可实现⽆状态、分布式的Web应⽤授权;官⽹:https://jwt.io,JWT的github地址:https://github.com/jwtk/jjwt

JWT数据格式

JWT包含三部分数据:

  • Header:头部,通常头部有两部分信息:
    • 声明类型,这⾥是JWT
    • 加密算法,⾃定义
      我们会对头部进⾏base64加密(可解密),得到第⼀部分数据
  • Payload:载荷,就是有效数据,⼀般包含下⾯信息:
    • ⽤户身份信息(注意,这⾥因为采⽤base64加密,可解密,因此不要存放敏感信息)
    • 注册声明:如token的签发时间,过期时间,签发⼈等
      这部分也会采⽤base64加密,得到第⼆部分数据
  • Signature:签名,是整个数据的认证信息。⼀般根据前两步的数据,再加上服务的的密钥(secret)(不要泄漏,最好周期性更换),通过加密算法⽣成。⽤于验证整个数据完整和可靠性

⽣成的数据格式如下:

一文秒懂JWT实现无状态登录_第2张图片
image.png

可以看到分为3段,每段就是上⾯的⼀部分数据

JWT交互流程

流程图如下:

一文秒懂JWT实现无状态登录_第3张图片
image.png

步骤翻译:
1、⽤户登录
2、服务的认证,通过后根据secret⽣成token
3、将⽣成的token返回给浏览器
4、⽤户每次请求携带token
5、服务端利⽤公钥解读jwt签名,判断签名有效后,从Payload中获取⽤户信息
6、处理请求,返回响应结果

因为JWT签发的token中已经包含了⽤户的身份信息,并且每次请求都会携带,这样服务的就⽆需保存⽤
户信息,甚⾄⽆需去数据库查询,完全符合了Rest的⽆状态规范。

结合Zuul的鉴权流程

我们逐步演进系统架构设计。需要注意的是:secret是签名的关键,因此⼀定要保密,我们放到鉴权中⼼保存,其它任何服务中都不能获取secret。

没有RSA加密时

在微服务架构中,我们可以把服务的鉴权操作放到⽹关中,将未通过鉴权的请求直接拦截,如图:

一文秒懂JWT实现无状态登录_第4张图片
image.png

流程解释:
1、⽤户请求登录
2、Zuul将请求转发到授权中⼼,请求授权
3、授权中⼼校验完成,颁发JWT凭证
4、客户端请求其它功能,携带JWT
5、Zuul将jwt交给授权中⼼校验,通过后放⾏
6、⽤户请求到达微服务
7、微服务将jwt交给鉴权中⼼,鉴权同时解析⽤户信息
8、鉴权中⼼返回⽤户数据给微服务
9、微服务处理请求,返回响应

发现什么问题了?
每次鉴权都需要访问鉴权中⼼,系统间的⽹络请求频率过⾼,效率略差,鉴权中⼼的压⼒较⼤。

结合RSA的鉴权

使用这个方式之前,咱们先大概了解一下RSA非对称加密。

⾮对称加密

加密技术是对信息进⾏编码和解码的技术,编码是把原来可读信息(⼜称明⽂)译成代码形式(⼜称密
⽂),其逆过程就是解码(解密),加密技术的要点是加密算法,加密算法可以分为三类:

  • 对称加密,如AES
    • 基本原理:将明⽂分成N个组,然后使⽤密钥对各个组进⾏加密,形成各⾃的密⽂,最后把所有的分组密⽂进⾏合并,形成最终的密⽂。
    • 优势:算法公开、计算量⼩、加密速度快、加密效率⾼
    • 缺陷:双⽅都使⽤同样密钥,安全性得不到保证
  • ⾮对称加密,如RSA
    • 基本原理:同时⽣成两把密钥:私钥和公钥,私钥隐秘保存,公钥可以下发给信任客户端
      • 私钥加密,持有私钥或公钥才可以解密
      • 公钥加密,持有私钥才可解密
    • 优点:安全,难以破解
    • 缺点:算法⽐较耗时
  • 不可逆加密,如MD5,SHA
    • 基本原理:加密过程中不需要使⽤密钥,输⼊明⽂后由系统直接经过加密算法处理成密⽂,这种加密后的数据是⽆法被解密的,⽆法根据密⽂推算出明⽂。

RSA算法历史:
1977年,三位数学家Rivest、Shamir 和 Adleman 设计了⼀种算法,可以实现⾮对称加密。这种算法⽤他们三个⼈的名字缩写:RSA

了解了RSA非对称加密之后咱们在说回结合RSA加密方式怎么来实现JWT鉴权流程。
直接看下面的流程图:

一文秒懂JWT实现无状态登录_第5张图片
image.png

流程解释:
1、我们⾸先利⽤RSA⽣成公钥和私钥。私钥保存在授权中⼼,公钥保存在Zuul和各个微服务
2、⽤户请求登录
3、授权中⼼校验,通过后⽤私钥对JWT进⾏签名加密
4、返回jwt给⽤户
5、⽤户携带JWT访问
6、Zuul直接通过公钥解密JWT,进⾏验证,验证通过则放⾏
7、请求到达微服务,微服务直接⽤公钥解析JWT,获取⽤户信息,⽆需访问授权中⼼

你可能感兴趣的:(一文秒懂JWT实现无状态登录)