欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JSON Web Token

程序员文章站 2024-02-04 08:09:22
...

首发于 个人博客
使用 JWT 开发过两个项目,其一是区块链轻钱包接口开发,另外一个项目是对接中国移动和某银行支付渠道。实现接口的授权和明文数据加密,确保客户端和服务器之间的数据安全传输,比较适合用在 HTTP 接口认证、数据加密传输的应用场景。
JSON Web Token (JWT) 是一种约定的开放标准 RFC7519 ,报文内容简洁且能够携带信息,方便安全地在客户端和服务器之间传输。加密之后的信息是可信任和可验证并能解密出明文,有两种方式加密:HMSC 算法(HS 256)、公私钥(RS256)
进一步解释 JWT 的两个特性

  • 简洁(compact): 由于加密后的 jwt token 串比较小,所以在网络传输时有很大的优势。可以拼接在 URL 中、可以放在 POST 请求 body 中或者放在 HTTP 请求头中。在传输过程中能够高效快速。
  • 携带信息(Self-contained): payload 包含用户必要的信息,减少服务端查询数据库次数。

JWT 使用场景

基本上有两种应用场景

  • 验签 Authentication:验签是最普遍用到的场景。当一个用户首次登录之后,后续前端所有的请求都携带服务器生成的 jwt token 串和服务器交互。轻量且没有跨域的特性,从而非常适合做单点登录。
  • 信息传输 Information Exchange:JWT 能够使用公私钥加密明文,服务端能够判断请求是否合法且能判断出是在与哪个账号进行交互。签名(Signature)能够计算出 header 和 payload,服务端能够判断密文是否被篡改。

JWT 的结构

JWT 有英文句号(.)分隔开的三部分组成,分别是:

  1. Header
  2. Payload
  3. Signature

所以,完整的 JWT 结构为

xxxx.yyyy.zzzz

就这三部分,进一步分别讨论。

Header

Header 由两部分组成:token 类型,值为 JWT ;算法类型,值为 HS256RS256,例如:

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

然后 JWT 通过 Base64Url 编码成 JWT 的第一部分

Payload

payload 包含了 claims ,其中 claims 大概有如下三种类型。

  • Reserved claims:这是 JWT 预定义的 claims ,非必需但推荐在 payload 中添加这种类型的 claims 。常见的有 iss(issuer), exp (expiration time), sub(subject),aud (audience)...
  • public claims:这些可以通过 JWTs 随意定义。但为了避免冲突,他们应该使用 IANA JSON Web Token Registry 定义或使用 URL 定义。
  • Private claims:自定义的的 claims,通常是客户端和服务端之间协商好需要的数据。

payload 的一个例子:

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

payload 的明文会被 Base64Url 编码为 JWT 的第二部分。

Signature

JWT 最后一部分是 Signature, 由第一部分和第二部分再加上指定的算法加密而得到。例如使用 SH 256 算法生成 signature

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

第三部分被用来验证客户端是谁,及确保密文没有被篡改。

总结

接口验签和明文加密,JWT 确实是一种不错的选择。现在开发 API 是比较常见的需求,对于后端开发者来说投入时间了解掌握 JWT 高收益的事儿。
在实际的开发过程中,官方及第三方开发者基本都开发出覆盖各种编程语言的 Libraries。接下来我打算用 Ruby 实现一个完整的 JWT 加密验签和解签的 Gem

参考阅读
Introduction to JSON Web Tokens