文章目录

  • 基于JWT的token认证机制
  • 1. 常见的认证(登录)机制
  • 1. Http Basic Auth
  • 2. Cookie Auth
  • 3. OAuth(开放授权)
  • 4. Token Auth(令牌认证) -》相当于尚方宝剑
  • 2. 基于JWT的token认证机制
  • 1.JWT组成
  • 3. JAVA的JJWT实现JWT
  • 1.token创建
  • 4. JWT +Redis登录方案
  • 1. 流程


基于JWT的token认证机制

1. 常见的认证(登录)机制

1. Http Basic Auth

简单说就是每次请求API时,都提供用户的username和password,即Basic Auth是
配合RESTful API使用的最简单的认证方式,只需提供用户名和密码即可,但存在把用
户名和密码暴露给第三方客户端的风险,因此,使用较少。

缺点:效率低
优点:无状态(服务器端无需存储登录信息)

2. Cookie Auth

Cookie认证机制就是为一次请求认证在服务端创建一个Session对象,同时在客户端
浏览器创建创建一个Cookie对象,通过客户端带上cookie对象与服务器端的Session
对象匹配来实现状态管理。

Cookie 不安全,容易csrf攻击
有状态的

3. OAuth(开放授权)

是一个开放授权的标准,允许用户让第三方应用访问该用户在某一web服务上存储的私密
资源,而无需用户名和密码。

4. Token Auth(令牌认证) -》相当于尚方宝剑
  1. 大概流程(即工作原理)为:
  1. 客户端使用用户名和密码请求登录
  2. 服务端收到请求,去验证用户名和密码
  3. 验证成功后,服务端会签发一个Token,然后将token发给客户端
  4. 客户端收到token后将其存储起来,如cookie
  5. 之后客户端再次发起请求时将token携带
  6. 服务端收到请求,先去验证请求中携带的token,若验证成功,返回请求内容
  1. 优点(相对于cookie)
  1. 支持跨域访问,cookie不支持
  2. 无状态:Token机制在服务端无需存储session信息,因为自身包含了
    用户登录的所有信息。(JWT方式将用户状态分散到了客户端中,相比于session,可以明显减轻服务端的内存压力),可轻松实现单点登录
  3. 更适用CDN,适用于移动端,
  4. 去耦:无需绑定到特定的身份验证方案,token可在任何地方生成,只要在api调用的时候,生成token调用即可。
    5.前后端分离,后端只负责通过暴露的RestApi提供数据,而页面的渲染、路由都由前端完成。因为rest是无状态的,不会记录到session中
  1. 缺陷
  1. JWT不适合存放大量信息,信息越多token越长
  2. JWT在生成token的时候支持失效时间,但是支持的失效时间是固定的.
    说明:【但是用户在等出(退出系统)的时候是随机触发的,那么jwt token来做这个失效是不可行的,因为jwt在初始化的时候已经定死在什么时候过期了。
    采用其他方案,在redis中存储token,设置token的过期时间,每次鉴权的时候都会去延长时间】

2. 基于JWT的token认证机制

JWT:JSON Web Token是一个轻巧的规范,允许我们使用jwt在用户和服务器之间传递安全可靠的信息,减轻对外部存储的依赖。
本质上是一个独立的身份验证令牌,可以包含用户标识、用户角色和权限等信息,以及您可以存储任何其他信息(自包含)。任何人都可以轻松读取和解析,并使用密钥来验证真实性。

1.JWT组成

一个JWT实际上就是一个字符串,由三部分组成,分别是头部、载荷与签名。即A.B.C的格式
A由JWT头部信息header加密得到
B由JWT用到的身份验证信息json数据加密得到
C由A和B加密得到,是校验部分

  1. 头部(Header)

用户描述该JWT的基本信息,例如其类型、签名所用算法等。可以通过一个json对象表示

{"typ":"JWT","alg":"HS256"}

最后对其进行Base64(JWT默认编码格式)编码为一串字符,即为A

  1. 载荷(playload)

存放有效信息的地方,有效信息包含三部分,分别是

  1. 标准中注册的声明(都非必须),见说明中
  2. 公共的声明(自定义)
  3. 私有的声明(自定义)
    说明
iss: jwt签发者
	sub: jwt所面向的用户,即登录的用户名
	aud: 接收jwt的一方
	exp: jwt的过期时间,需大于签发时间
	nbf: 定义在什么时间之前,该jwt是不可用的
	iat: jwt签发时间
	jti: jwt的唯一身份标识,用来作为一次性token

如:

{"sub":"123456","name":"jhon","admin":true}

最后对其进行Base64(JWT默认编码格式)编码为一串字符,即为B
Base64算法是可逆的,不可以在载荷部分保存用户密码等敏感信息

  1. 签证(signature)
    签证由三部分组成

头部(Header)->BASE64后的,标记为X
载荷(playload)->BASE64后的,标记为Y
secret(盐),标记为Z
header的alg(加密方式),标记为U

该部分需要BASE64加密后的Header(即X)和BASE64加密后的playload(即Y)通过.连接组成的字符串,
然后通过header中声明的加密方式进行加盐(secret)组合加密构成jwt的第三部分。
U(X.Y.Z)
将这三部分通过.连接构成的字符串即为最终的jwt
注意部分:

  1. secret 是保存在服务器端的,
  2. jwt的签发生成也是在服务器端的
  3. secret 就是用来签发和验证jwt的,所以,是服务端的私钥,不能暴露
  4. 签证的目的是用来验证头部和载荷是否被非法篡改。

验签过程描述:获取token值,读取Header部分并Base64解码,得到签名算法。根据以上方法算出签名,如果签名信息不一致,说明是非法的。

3. JAVA的JJWT实现JWT

1.token创建

1.pom引入依赖

待补充

4. JWT +Redis登录方案

1. 流程
  1. 前端服务器收到用户登录请求,传给后台API网关。
  2. API网关把请求分发到用户服务里进行身份验证。
  3. 后台用户服务验证通过,然后从账号信息抽取出userName、login_time等基本信息组成payload,进而组装一个jwt,把jwt放入redis(因为退出的时候无法使jwt立即作废,所以使用保存在redis中,退出的时候delete掉就可以了,鉴权的时候加一层判断jwt是否在redis里,如果不在则证明jwt已过期作废),然后包装cookie中返回到前端服务器,这就登录成功了。
    前端服务器拿到jwt,进行存储(可以存储在缓存中,也可以存储在数据库中,如果是浏览器,可以存储在 localStorage 中,或放入到cookie里面)
    登录后,再访问其他微服务的时候,前端会携带jwt访问后台,后台校验 JWT,验签通过后,返回相应资源和数据就可以了。