JSON Web Token

首发于 个人博客
使用 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

你可能感兴趣的:(JSON Web Token)