Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JWT 概念 #45

Open
ChuChencheng opened this issue Jun 5, 2021 · 0 comments
Open

JWT 概念 #45

ChuChencheng opened this issue Jun 5, 2021 · 0 comments
Labels

Comments

@ChuChencheng
Copy link
Owner

什么是 JWT

JWT (JSON Web Token) 是一个公开的标准(RFC 7519),其定义了一种紧凑且独立的方式,使双方可以用 JSON 格式安全地传输信息。使用数字签名使得传输的信息可以被校验和信任。JWT 可以使用一个 secret 签名(HMAC 算法),也可以使用公钥秘钥进行签名(RSA,ECDSA 等)。

JWT 的用途

JWT 通常用于以下几个场景:

  • 授权校验(Authorization):当用户登录后,收到服务端签发的 JWT ,在后续请求中都带上这个 token ,以获得权限访问服务端的资源等。由于 JWT 的体积小,易于跨域名使用,其也被广泛应用于单点登录(SSO)的场景中。
  • 信息交换(Information Exchange):由于 JWT 是经过签名的,可以确保发送者的身份。除此之外,签名是由 header 与 payload 计算出来的,你也可以校验接收到的 JWT 是否被篡改。

JWT 的结构是什么样的

压缩过的 JWT 由三个部分组成,以 . 连接:

  • Header
  • Payload
  • Signature

因此 JWT 看起来会像是如下结构:

xxxxx.yyyyy.zzzzz

逐个拆解一下

Header

Header 部分一般包含两个字段

  • typ:token 类型,JWT
  • alg:签名所使用的算法,例如 HMAC SHA256 或 RSA 等

示例:

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

将这串 JSON 经过 Base64 编码后,就得到了 Header 部分

Payload

Payload 部分是一些声明,一般包含对一个实体(例如用户)的描述与一些额外的信息。

声明有三种:

  • registered
  • public
  • private

Registered claims

这部分声明是预定义的,在标准中推荐有但不强制。提供一系列有用的、用于信息交换的声明。

包括以下字段:

  • iss (Issuer) 表明是谁签发了这个 JWT
  • sub (Subject) 表明了 JWT 签发的对象,区分不同的用户(参考与 aud 的区别
  • aud (Audience) 表明用户拿到签发的 JWT 后,会把该 JWT 用于哪个接收者
  • exp (Expiration Time) 过期时间
  • nbf (Not Before) 在这个时间之前 JWT 不生效
  • iat (Issued At) 签发时间
  • jti (JWT ID)

(claims 字段都只有三个字母,是为了保持紧凑)

Public claims

这部分声明可以按使用者的意愿来定义,但是需要避免与其他字段的冲突,因此,这部分字段应该在 IANA JSON Web Token Registry 中有定义,或者应被定义为一个带有不冲突命名空间的 URI 。

Private claims

这部分自定义的声明应是使用 JWT 的双方约定好的字段,并且不能是 registered 或者 public 中的声明。

Payload 示例:

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

将 Payload 部分经过 Base64 编码后,组成 JWT 的第二部分

注意:JWT 虽然可以防止篡改,但是其内容是对任何人可见的,不要将任何未加密的私密信息放入 JWT 中。

Signature

将编码过的 Header, Payload 和一个 secret ,经过 Header 中指定的算法进行签名,即可得到 Signature 部分

例如,如果使用 HMAC SHA256 算法,签名将这样生成:

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

签名用于验证信息在传输途中没有被篡改,并且如果是使用私钥进行签发,还可以验证签发者的身份。

将三段内容组合

把三段 Base64 编码过的内容组合起来,并用 . 连接,即可得到一串 JWT 。

JWT 工作原理

  1. 当用户登录后,服务端签发一个 JWT 给客户端
  2. 用户在后续请求中,将 JWT 随请求附上
  3. 服务端验证请求中的 JWT ,验证通过后正常返回资源,否则提示未授权

一个简易的时序图:

image

客户端一般会将 JWT 附在 Authorization Header 中,使用 Bearer 模式,例如:

Authorization: Bearer <token>

使用这种方式传输 JWT ,可以跨域使用,因为不是使用 Cookie 。

JWT 特点

  • 轻量、易传输
  • 可非对称加密
  • JSON 格式对大部分编程语言友好

Reference

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant