文章目录
- 基于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(令牌认证) -》相当于尚方宝剑
- 大概流程(即工作原理)为:
- 客户端使用用户名和密码请求登录
- 服务端收到请求,去验证用户名和密码
- 验证成功后,服务端会签发一个Token,然后将token发给客户端
- 客户端收到token后将其存储起来,如cookie
- 之后客户端再次发起请求时将token携带
- 服务端收到请求,先去验证请求中携带的token,若验证成功,返回请求内容
- 优点(相对于cookie)
- 支持跨域访问,cookie不支持
- 无状态:Token机制在服务端无需存储session信息,因为自身包含了
用户登录的所有信息。(JWT方式将用户状态分散到了客户端中,相比于session,可以明显减轻服务端的内存压力),可轻松实现单点登录- 更适用CDN,适用于移动端,
- 去耦:无需绑定到特定的身份验证方案,token可在任何地方生成,只要在api调用的时候,生成token调用即可。
5.前后端分离,后端只负责通过暴露的RestApi提供数据,而页面的渲染、路由都由前端完成。因为rest是无状态的,不会记录到session中
- 缺陷
- JWT不适合存放大量信息,信息越多token越长
- 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加密得到,是校验部分
- 头部(Header)
用户描述该JWT的基本信息,例如其类型、签名所用算法等。可以通过一个json对象表示
{"typ":"JWT","alg":"HS256"}
最后对其进行Base64(JWT默认编码格式)编码为一串字符,即为A
- 载荷(playload)
存放有效信息的地方,有效信息包含三部分,分别是
- 标准中注册的声明(都非必须),见说明中
- 公共的声明(自定义)
- 私有的声明(自定义)
说明
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算法是可逆的,不可以在载荷部分保存用户密码等敏感信息
- 签证(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
注意部分:
- secret 是保存在服务器端的,
- jwt的签发生成也是在服务器端的
- secret 就是用来签发和验证jwt的,所以,是服务端的私钥,不能暴露
- 签证的目的是用来验证头部和载荷是否被非法篡改。
验签过程描述:获取token值,读取Header部分并Base64解码,得到签名算法。根据以上方法算出签名,如果签名信息不一致,说明是非法的。
3. JAVA的JJWT实现JWT
1.token创建
1.pom引入依赖
待补充
4. JWT +Redis登录方案
1. 流程
- 前端服务器收到用户登录请求,传给后台API网关。
- API网关把请求分发到用户服务里进行身份验证。
- 后台用户服务验证通过,然后从账号信息抽取出userName、login_time等基本信息组成payload,进而组装一个jwt,把jwt放入redis(因为退出的时候无法使jwt立即作废,所以使用保存在redis中,退出的时候delete掉就可以了,鉴权的时候加一层判断jwt是否在redis里,如果不在则证明jwt已过期作废),然后包装cookie中返回到前端服务器,这就登录成功了。
前端服务器拿到jwt,进行存储(可以存储在缓存中,也可以存储在数据库中,如果是浏览器,可以存储在 localStorage 中,或放入到cookie里面)
登录后,再访问其他微服务的时候,前端会携带jwt访问后台,后台校验 JWT,验签通过后,返回相应资源和数据就可以了。