JWT 与 access_token、refresh_token

781 阅读2分钟
前言:最近一直在看 SpringSecurity 整合 Oauth2,想着写点什么。

一、JWT(json web token)

  1. 概念

    JWT定义了一种紧凑的,自包含的形式,被用作在网络中安全的传输信息。

  2. 格式

    例如:xxxx.yyyyyyyy.zzz

    根据.分割,可以得到三部分,header,payload, signature。每部分可以使用Base64解码,就是一个JSON对象。

    payload中会包含当前jwt的颁发者信息,JWT有效期,用户的凭证,权限信息,和用户自定义的信息等等。由于JWT是明文信息,所以不适合将一些敏感信息保存在JWT中。

    jwt解析: https://jwt.io
    
  3. 安全在哪体现

    JWT的安全性,说的是自身信息是防篡改,体现在它的签名部分signature。我们可以在生成JWT的时候,使用数字证书进行签名,采用非对称加密,可以很大程度的保证JWT的安全性。JWT默认是非加密的。

    但是,JWT一经颁发,将无法回收。如果发生泄漏,将无法阻止,这也是众所周期的JWT最大的问题。

注:JWT 也是 客服端-服务器 在 用户身份信息认证 使用 token 形式 的一种体现。JWT 将用户身份信息认证 保存在客户端,服务端也就不用维护用户状态,大大减轻了服务器的压力。客户端每次请求中,只需要携带这个JWT信息,服务端根据JWT信息进行身份认证即可。

二、OAuth2(认证)

由上述可知,JWT存在颁发不可回收问题。如果JWT信息发生泄漏,就可以凭借此信息一直访问服务器信息,只有等到JWT自动过期,用户的信息才会失效。
​
那么我们怎么维护用户身份信息呢?
​
我们可能最先想到,使用 Redis(数据库) 保存JWT信息,将信息维护服务器。
如果我们真的使用这种方式,那不就又回到了最初的使用服务端保存token的方式了吗?那这个JWT还有存在的必要吗?
​
第二种方式,我们尽可能短的设置JWT的有效时间,那么,就算用户的JWT信息泄露了,对系统的访问时间也就尽可能的短了。
而在OAuth2中提出了 access_token 和 refresh_token 这两个概念。
  1. access_token

    用于在客户端的一般请求中,使用此JWT信息验证用户身份。它的有效期通常设置的很短。

  2. refresh_token

    用于在access_token失效时,交换新的access_token

注:可见使用此种方式,我们平衡了 JWT能减轻服务端的压力 与 JWT的泄露带来的危害。转而需要关心的是系统对JWT泄露后访问时间的容忍程度。对于安全性高,保密性强的系统,这种方式确实不合适,最好还是使用session。

其原理如图

access_token与refresh_token的使用.jpg