JWT 身份认证模式

基于session 的方式存在的问题

  1. 服务器端需要存储 session,并且由于 Session 需要经常快速查找,所以通常存储在内存中,或者内存数据库中。如果同时又大量用户在线,就会占用大量的服务器资源

  2. 当需要扩展时候,创建 session 的服务器可能不是验证 session的服务器,所以还需要将所有 session 单独存储并共享,后来又有人想到,把所有的 seesionid 放到同一台电脑上,让所有的用户都访问这同一台电脑,但是如果那个存储 sessionid 的服务器挂掉了,那就要让所有的用户都得重登。

  3. 由于客户端使用 cookie 储存 SessionID , 在跨域场景下需要进行兼容性处理,同时这些方法也难以方法 CSRF 攻击

Token 认证模式

基于 session 存在的这些问题,所有就有人在想,凭什么让我去保存这些该死的 sessionId,让用户自己存就好了,那么当用户把 认证信息传过来的时候,我怎么判断这个是我颁发的,还是他自己伪造的?这其实就变成了一个验证的问题。

Token 的流程

  1. 服务端使用用户名、密码进行认证
  2. 服务端验证用户名、密码正确以后,生成 Token 返回给客户端
  3. 客户端保存 Token,访问需要认证的接口时,在 url 参数或 HTTP Header 中加入 Token
  4. 客户端通过解码 Token 进行鉴权,返回给客户端需要的数据

Token 的优势

可扩张性

在客户端存储的Tokens是无状态的,并且能够被扩展。基于这种无状态和不存储Session信息,负载负载均衡器能够将用户信息从一个服务传到其他服务器上。

安全性

请求中发送token而不再是发送cookie能够防止CSRF(跨站请求伪造)。即使在客户端使用cookie存储token,cookie也仅仅是一个存储机制而不是用于认证。不将信息存储在Session中,让我们少了对session操作。

token是有时效的,一段时间之后用户需要重新验证。我们也不一定需要等到token自动失效,token有撤回的操作,通过token revocataion可以使一个特定的token或是一组有相同认证的token无效。

可扩展性

使用tokens时,可以提供可选的权限给第三方应用程序。当用户想让另一个应用程序访问它们的数据,我们可以通过建立自己的API,得出特殊权限的tokens。

Refresh Token

通常 access token 的有效期会比较短(一般10分钟),refresh token,的时间比较长(比如 7 天),当用户的 access token 过期的时候,可以使用 refresh token 来动态刷新 access token ,如果 refresh token 也过期了,那么用户就只能重新登录了。

JWT 引入 Refresh Token 以后的工作流程

  1. 用户使用用户名字和密码进行登录

  2. 服务器端生成有效期较短的 Access Token ,和有效期较长的 refresh token

  3. 访问接口的时候,携带的是 Access Token

  4. 如果 Access Token 过期了,则用户就会使用 refresh token向刷新接口请求新的 access token

  5. 如果 refresh token 也过期了,那么只能重新登录了

JWT 的劣势

在实际的生产环境中,使用 jwt逻辑进行鉴权的,其实比较少(最起码,我遇到过的项目,基本没有用的)。这主要是因为使用 jwt 配置较为复杂,且每次通信,都要进行解密token,比较消耗性能。至于其扩展性,现在完全可以在集群内创建一个公用的 redis存储 sessionId,就可以实现集群内的服务共享,且只要鉴权的这个服务没挂,就没事。

参考文献

https://blog.csdn.net/whl190412/article/details/90024671?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242

posted @ 2021-07-12 21:42  沧海一声笑rush  阅读(73)  评论(0编辑  收藏  举报