Published on

终于知道什么是JWT!

Authors
  • avatar
    Name
    Joy Peng
    Twitter

What is JWT?

先看一下官方定义:

JSON Web Token(JWT)是一种开放标准(RFC 7519),定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息作为 JSON 对象。这些信息可以被验证和信任,因为它是数字签名的。JWT 可以使用密钥(使用 HMAC 算法)或使用 RSAECDSA 的公钥/私钥对进行签名。

有点难懂?没关系,我们先来看一组概念:

Authorization & Authentication

  1. authentication: the process of verifying who you are

    认证是验证用户是谁的过程。通常,用户需要提供用户名和密码,然后服务器验证这些凭据是否正确。

  2. Authorization: the process of verifying what you have access to

    授权是验证用户是否有权访问某些资源的过程。通常,用户在登录后,服务器会返回一个token,这个token包含了用户的权限信息。用户在访问受保护的资源时,需要将这个token发送给服务器,服务器会验证这个token是否有效,如果有效,就允许用户访问资源。

例如,当您在机场通过安检时,您需要出示您的身份证以验证您的身份。然后,当您到达登机口时,您向空乘人员出示登机牌,以便他们授权您登机并允许进入飞机。

Session & Token

授权的方式通常有两种:sessiontoken

  1. Session
session

session的工作流程如下:

  • 用户登录,服务器验证用户的用户名和密码,如果正确,服务器会创建一个sessionsession存储在服务器端,通常是在内存中。
  • 服务器返回一个session id,这个session id存储在cookie中,每次用户访问受保护的资源时,浏览器会自动发送这个cookie给服务器。
  • 服务器接收到请求后,会检查session id是否有效,如果有效,就允许用户访问资源。

优缺点:

  • 服务器需要存储session,如果用户量很大,服务器的内存会很快被占满。session是存储在服务器端的,如果服务器重启,session会丢失,用户需要重新登录。 -session是存储在服务器端的,用户无法修改session,保证了安全性。
  1. Token

除了使用session cookie,另一种方式是JSON web token.

session
  • 客户端给服务端发请求,服务端通过使用私钥加密的方式生成一个JWT token,返回给客户端。
  • JWT Token存储在客户端,通常是在local storage或者cookie中。
  • 每当用户想要访问受保护的路由或资源时,应发送JWT给服务端。通常在Authorization header中使用如下格式:

Authorization: Bearer <token>

  • 服务器将检查Authorization标头中是否存在有效的JWT,验证过程如下:
    • 验证JWT的签名是否有效:使用公钥解密JWT,如果成功,说明JWT没有被篡改。
    • 验证JWT是否过期: JWT包含了一个exp字段,表示JWT的过期时间,服务器会检查当前时间是否在过期时间之前。
    • 验证JWT是否包含正确的权限: JWT包含了用户的权限信息,服务器会检查JWT是否包含了访问资源所需的权限。

TIP

  1. 如果通过 HTTP 标头发送 JWT 令牌,则应尽量防止它们变得太大。某些服务器不接受超过 8 KB 的标头。如果尝试在 JWT 令牌中嵌入太多信息(例如包含所有用户权限),则可能需要替代解决方案,例如 Auth0 细粒度授权。
  2. 如果令牌在 Authorization Header中发送,则跨域资源共享 (CORS) 不会成为问题,因为它不使用cookie

Structure of JWT

JSON的紧凑形式由三部分组成,用点(.)分隔,分别是:

  • Header
  • Payload
  • Signature
xxxxx.yyyyy.zzzzz
  1. Header

    Header是一个JSON对象,通常由两部分组成:令牌类型(即 JWT)和正在使用的签名算法(如 HMAC SHA256 或 RSA)。

  2. Payload

    也是一个json对象,其字段有三种类型

    • Registered claims:

      JWT 规范推荐的标准化声明。

              iss (issuer):签发人
              exp (expiration time):过期时间
              sub (subject):主题
              aud (audience):受众
              nbf (Not Before):生效时间
              iat (Issued At):签发时间
              jti (JWT ID):编号
      
    • Private claims: 这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,既不是注册声明也不是公开声明。

    • Public claims: 可由用户定义,但应注册或使用唯一的命名空间以避免冲突。

    example payload:

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

    要创建签名部分,您必须获取Base64Url 编码后的的headerpayload 以及secret并使用标头中使用的算法并对其进行签名。由于进行了签名,任何对它的篡改都会被发现。

TIP

JWT 作为一个令牌(token),有些场合可能会放到 URL(比如 api.example.com/?token=xxx)。Base64 有三个字符+、/和=,在 URL 里面有特殊含义,所以要被替换掉:=被省略、+替换成-,/替换成_ 。这就是 Base64URL 算法。

JWT的特点

  1. JWT十分紧凑,适合在HTTP请求的头部发送,或者作为POST参数发送。
  2. JWT使用的签名算法是HMAC SHA256或RSA,使用私钥签名,使用公钥验证签名。
  3. JWT可以跨平台使用,服务端只需要存储一个密钥,就可以验证JWT的有效性。
  4. JWT 的payload通常不加密,因此不要在 JWT 中加入敏感信息。为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。
  5. JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。
  6. JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。
  7. JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。

References

  1. https://www.youtube.com/watch?v=7Q17ubqLfaM
  2. https://jwt.io/introduction
  3. https://www.youtube.com/watch?v=mbsmsi7l3r4
  4. https://www.youtube.com/watch?v=AcYF18oGn6Y
  5. https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html