在OAuth 2.0中,如何使用JWT结构化令牌?
JWT 结构化令牌
JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为 JSON 对象在各方之间安全地传输信息。
JWT 这种结构化体可以分为:
HEADER(头部)
PAYLOAD(数据体)
SIGNATURE(签名)
经过签名之后的 JWT 的整体结构,是被句点符号分割的三段内容,结构为
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJzdWIiOiJVU0VSVEVTVCIsImV4cCI6MTU4NDEwNTc5MDcwMywiaWF0IjoxNTg0MTA1OTQ4MzcyfQ.
1HbleXbvJ_2SW8ry30cXOBGR9FW4oSWBd3PWaWKsEXE
注意:JWT 内部没有换行,这里只是为了展示方便,才将其用三行来表示。
HEADER 表示装载令牌类型和算法等信息,是 JWT 的头部。其中,typ 表示第二部分 PAYLOAD 是 JWT 类型,alg 表示使用 HS256 对称签名的算法。(摘要算法?)
PAYLOAD 表示是 JWT 的数据体,代表了一组数据。其中,sub(令牌的主体,一般设为资源拥有者的唯一标识)、exp(令牌的过期时间戳)、iat(令牌颁发的时间戳)是 JWT 规范性的声明,代表的是常规性操作。更多的通用声明,你可以参考 RFC 7519 开放标准。不过,在一个 JWT 内可以包含一切合法的 JSON 格式的数据,也就是说,PAYLOAD 表示的一组数据允许我们自定义声明。
SIGNATURE 表示对 JWT 信息的签名。那么,它有什么作用呢?我们可能认为,有了 HEADER 和 PAYLOAD 两部分内容后,就可以让令牌携带信息了,似乎就可以在网络中传输了,但是在网络中传输这样的信息体是不安全的,因为你在“裸奔”啊。所以,我们还需要对其进行加密签名处理,而 SIGNATURE 就是对信息的签名结果,当受保护资源接收到第三方软件的签名后需要验证令牌的签名是否合法。(最后一句表述不清, 应该是平台要对 access_token 进行签名验证)
令牌内检
什么是令牌内检呢?授权服务颁发令牌,受保护资源服务就要验证令牌。同时呢,授权服务和受保护资源服务,它俩是“一伙的”,受保护资源来调用授权服务提供的检验令牌的服务,我们把这种校验令牌的方式称为令牌内检。
在如今已经成熟的分布式以及微服务的环境下,不同的系统之间是依靠服务而不是数据库来通信了,比如授权服务给受保护资源服务提供一个 RPC 服务:
JWT 是如何被使用的?
有了 JWT 令牌之后的通信方式,授权服务“扔出”一个令牌,受保护资源服务“接住”这个令牌,然后自己开始解析令牌本身所包含的信息就可以了,而不需要再去查询数据库或者请求 RPC 服务。这样也实现了我们上面说的令牌内检。
JWT 令牌需要在公网上做传输。所以在传输过程中,JWT 令牌需要进行 Base64 编码以防止乱码,同时还需要进行签名及加密处理来防止数据信息泄露。
为什么要使用 JWT 令牌?
第一,JWT 的核心思想,就是用计算代替存储,有些 “时间换空间” 的 “味道”。当然,这种经过计算并结构化封装的方式,也减少了“共享数据库” 因远程调用而带来的网络传输消耗,所以也有可能是节省时间的。
第二,也是一个重要特性,是加密。因为 JWT 令牌内部已经包含了重要的信息,所以在整个传输过程中都必须被要求是密文传输的,这样被强制要求了加密也就保障了传输过程中的安全性。这里的加密算法,既可以是对称加密,也可以是非对称加密。
第三,使用 JWT 格式的令牌,有助于增强系统的可用性和可伸缩性。这种 JWT 格式的令牌,通过“自编码”的方式包含了身份验证需要的信息,不再需要服务端进行额外的存储,所以每次的请求都是无状态会话。这就符合了我们尽可能遵循无状态架构设计的原则,也就是增强了系统的可用性和伸缩性。
缺点:
没办法在使用过程中修改令牌状态 (无法在有效期内停用令牌)
解决:
一是,将每次生成 JWT 令牌时的秘钥粒度缩小到用户级别,也就是一个用户一个秘钥。这样,当用户取消授权或者修改密码后,就可以让这个密钥一起修改。一般情况下,这种方案需要配套一个单独的密钥管理服务。
二是,在不提供用户主动取消授权的环境里面,如果只考虑到修改密码的情况,那么我们就可以把用户密码作为 JWT 的密钥。当然,这也是用户粒度级别的。这样一来,用户修改密码也就相当于修改了密钥。
令牌的生命周期
第一种, 令牌的自然过期过程: 从授权服务创建一个令牌开始,到第三方软件使用令牌,再到受保护资源服务验证令牌,最后再到令牌失效。同时,这个过程也不排除主动销毁令牌的事情发生,比如令牌被泄露,授权服务可以做主让令牌失效。
第二种情况, 访问令牌失效之后可以使用刷新令牌请求新的访问令牌来代替失效的访问令牌,以提升用户使用第三方软件的体验
第三种情况,就是让第三方软件比如小兔,主动发起令牌失效的请求,然后授权服务收到请求之后让令牌立即失效
往期推荐
🧐分享、点赞、在看,给个三连击呗!👇