什么是 JSON Web Tokens?

JSON Web Token(JWT)一个开发的标准(RFC7519),用户在各方之间作为JSON对象安全的传输信息。该信息可以被验证和信任,因为它是经过数字签名的。

JWT虽可以在各方之间提供保密,但我们的侧重点是签名令牌,签名令牌可以验证其中包含的声明的完整性,而加密令牌则对其他地方隐藏这些声明。

当使用公钥/私钥对对令牌进行签名时,签名还证明只有持有私钥的一方才是对其进行签名的一方。

什么时候应该使用 JSON Web Tokens?

授权:JWT中最常见的场景,用户登录过后,每个后续请求中都包含JWT,允许用户访问该令牌允许的路由、资源。同时因为开销小,并且能轻松跨不同区域使用。

信息交换: JSON Web Tokens 是一种安全信息传输的好方法,进行双方信息传输过程之中,由于使用标头和有效负载计算签名,因此还可以验证内容是否未被篡改。

JSON Web Token 结构?

在其紧凑形式中,JSON Web Tokens 由用(.)分隔的三个组成部分,分别是:

  • header(标签)
  • payload(载荷)
  • signature(签名)

举例通常形式为:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.(header)

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.(payload)

XbPfbIHMI6arZ3Y922BhjWgQzWXcXNrz0ogtVhfEd2o(signature)

接着我们再来看看结构标题(header)的结构:

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

标头通常由两部分组成:令牌的类型(Typ)即JWT,以及正在使用的签名算法。例如HMAC SHA256 或RSA。

typ及alg属性的全程其实是type和algorithm,分别就是类型与算法的意思。之所以用三个字母,基于考虑JWT最终字符串大小的考虑,同时也是跟JWT名称保持一致长度,这个理由。。。skr。签发JWT时这些名称都可以换掉但是最后可能会出现种种问题。

最后,我们将此JSON进行Base64Url编码以形成 JWT 的第一部分

image-20211101205751453

再看看payload(有效载荷)部分的结构和生成过程:

有效载荷实例:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

payload从结构上来说与header结构相差不大,但是payload是用来承载要传递的数据,它的json结构实际上是对JWT要传递的数据的一组声明,这些声明被JWT标准称为claim,它的一个“属性值对”其实就是一个claim,每一个claim的都代表特定的含义和作用。

sub可以想象成就是token,name为用户名称,admin表示是否为管理员角色。当JWT进行验证时,这些claim就发挥了他们特定的作用。

有效负载(payload)共有三种类型的声明:注册声明公共声明和私人声明。

  • 注册声明:这些是一组预定义的声明,这些声明不是强制性的,而是推荐的,以提供一组有用的、可互操作的声明。其中一些是: iss(发行者)、 exp(到期时间)、 sub(主题)、 aud(受众)

请注意,声明名称只有三个字符,因为 JWT 是紧凑的。

  • 公共声明:这些可以由使用 JWT 的人随意定义。但是为了避免冲突,它们应该在IANA JSON Web Token Registry中定义或定义为包含抗冲突命名空间的 URI。
  • 私人权利:这些都是使用它们同意并既不是当事人之间建立共享信息的自定义声明注册公众的权利要求。

最后也是把这个json结构做base64url编码之后,就能生成payload部分的串:

image-20211101205657390

最后再看signature部分的生成过程:签名是把header和payload对应的json结构进行base64url编码后得到两个串用英文下的句号进行拼接的。然后根据header中的alg签名算法再进行生成。算法不同,生成的结果也是截然不同的。但是最终要解决的问题是一样的。

例如,如果要使用 HMAC SHA256 算法,则签名将通过以下方式创建:

HMACSHA256(  //包含两种算法一种是HMAC算法和SHA256算法,前者用于生成摘要,后者用于对摘要进行数字签名,统称HMACSHA256。
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

签名用于验证消息在此过程中没有更改,并且在使用私钥签名的令牌的情况下,它还可以验证 JWT 的发送者是它所说的那个人。

我们将header标题及payload有效负载在在线工具中进行在线签名得出结果。将header与payload用英文下的句号串联起来。用”secret(秘密)“ 作为密钥进行测试。 进行计算……

image-20211102001350430

最后的结果为结果B项,与我们JSON Web Token 结构中举出的例子得到的结果一致。

在线工具-够测试签名算法(https://1024tools.com/hmac)

在于最后是否有“=”字符。这个区别产生的原因在于上图中的JWT是通过JWT的实现库签发的JWT,这些实现库最后编码的时候都用的是base64url编码,而前面那些在线工具都是bas64编码,这两种编码方式不完全相同,导致编码结果有区别。

以上就是一个JWT包含的全部内容以及它的签发过程。

后面就来看看该如何去验证一个JWT是否为一个有效的JWT。但是夜已深,今天就到这里Skr~~~。

最后修改:2021 年 11 月 02 日
如果觉得我的文章对你有用,请随意赞赏