- 2021/09/20, jwt.io 上的 "secret base64 encoded"
- 2021/12/25, Nginx JWT 认证
- 2022/03/09, Golang JWT
- 2022/03/28, 和 JWT 关系密切的一些规范
JWT 介绍
一句话介绍 JWT:就是通过非对称加密算法签名的方式,将部分用户信息存在客户端。
全名 JSON Web Token,简称 JWT。
内容 = 头 Headers (JSON) + 负载 Payload (JSON) + 签名 Signature
分别 Base64 编码之后,用 .
连接。
JSON 实现
import base64
def jsonify(obj):
return json.dumps(obj, ensure_ascii=False, separators=',:')
def base64urlEncoding(s):
return base64.urlsafe_b64encode(s).rstrip(b'=').decode('ascii')
def sign(key, msg):
return base64urlEncoding(hmac.new(key, msg, hashlib.sha256).digest())
# def verify(key, msg, sig):
# return key.verify(msg, base64.urlsafe_b64decode(sig))
def e(obj):
return base64urlEncoding(jsonify(header).encode('utf-8'))
def encode(key, header, payload):
s = e(header) + '.' + e(payload)
return s + '.' + sign(key, s)
def decode(token):
header_str, payload_str, sig = token.split('.')
header = json.loads(base64.urlsafe_b64decode(header_str).decode('utf-8'))
payload = json.loads(base64.urlsafe_b64decode(payload_str).decode('utf-8'))
sig = base64.urlsafe_b64decode(sig)
header = {
"alg": "HS256",
"typ": "JWT"
}
payload = {
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
signature = HMAC_SHA256(
secret,
base64urlEncoding(header) + '.' +
base64urlEncoding(payload)
)
const token = base64urlEncoding(header) + '.' + base64urlEncoding(payload) + '.' + base64urlEncoding(signature)
标准字段
Claim 字段
Code | Name | Description |
---|---|---|
iss |
Issuer | .. |
sub |
Subject | .. |
aud |
Audience | .. |
exp |
Expiration Time | .. |
nbf |
Not Before | .. |
iat |
Issued At | .. |
jti |
JWT ID | .. |
Header 字段
Code | Name | Description |
---|---|---|
typ |
Type | .. |
cty |
Content Type | .. |
alg |
Algorithm | .. |
kid |
Key ID | .. |
x5c |
X.509 Certificate | .. |
x5u |
X.509 URL | .. |
x5t |
X.509 Thumbprint | .. |
jku |
JSON Web Key URL | .. |
jwk |
JSON Web Key | .. |
x5t#S256 |
X.509 SHA-256 Thumbprint | .. |
关于 JWT 的看法
- 相比 Session,减少了 DB/Redis 操作。
- 如果需要注销功能(踢下线),可以加一个黑名单,验证服务定时拉取这个黑名单
- 服务降级的时候,这一步可以去掉
- 相比加密 Cookie,不用依赖 HTTP Cookie,更加灵活,适用更多场景。
- 应该尽可能保证 Token 不要太长
- 顶多 4、5 个字段就够了
- JWT 和 加密 Cookie 一样,如果需要存储的信息太多,还是会让请求有点臃肿
- 大部分时候只需要验证身份,没有太多信息存储的需求,JWT
- 可以在网关那边统一校验
- 跨域