JWT = Json Web Token

概述

应用于 http 接口协议的鉴权的方式。用来制作后端对前端返回的登录态。

基于 http 的 restful 接口一般是无状态的,在原始的协议中客户端向服务端发起一个请求后,服务端需要根据客户端的请求直接做个回复。而在计算机网络应用的发展过程中,逐渐出现了 Restful 协议。该协议事实上已经成为目前 web 应用的主流协议。

然而,http 的无状态特性已经无法满足当前应用发展的需求。在服务端收到客户端的请求之后,还要验证客户端是否有效,用户是否有效,还要根据用户的当前状态返回各种这样的不同的响应。这时候就出现了一个问题:“服务端该如何判断客户端当前的登录状态呢?”

JWT 就是解决这个问题的一个“补丁”。在用户登录之后,服务端会返回一个 token(一张入场券),每次客户端发起请求时都会带着这个入场券,这样服务端就能判断当前客户端上用户是谁了。

解决用户授权的方式有很多,只不过 JWT 已经成为了一种事实上的鉴权标准被广泛使用。

详情

JWT 是一长串字符串,用于表示用户的登录态。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

中间以 . 分隔,分为三个部分

  • 第一部分 header:一些“元数据”,说明用什么算法,这是个啥。用 base64 编码
  • 第二部分 payload:放了一点有效信息,可以自行定义,例如用户名,用户 id,是否是管理员。这部分内容用 base64 编码,并不加密
  • 第三部分 signature:签名,对前两部分做了签名,并用 secret 加密保证 JWT 无法被篡改。

其中的每个部分,在 base64 编码之前是序列化的 json 字符串,使用不同语言处理起来都比较方便。

特性

JWT 拥有不错的特性,可以理解为是一种协议设计的最佳实践:

  • 明文性:base64 可以被立即解码,所以 JWT 中的所有信息都是明文的
  • 防篡改:签名可以保证 header 和 payload 部分篡改
  • 处理方便:json 在各个语言中的支持都非常到位,所以用起来非常方便

双令牌结构

包含两个令牌,可以保证更好的安全性和用户体验。

  • Access Token 访问令牌 - 短期:用于用户访问资源的令牌,时间很短。经常被传输。
  • Refresh Token 刷新令牌 - 长期:用于刷新访问资源的令牌,时间较长。不经常被传输。被截获的可能性小。

相关的库

  • python: pyjwt
  • go: jwt

参考文档