TOC

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 的看法

  1. 相比 Session,减少了 DB/Redis 操作。
  2. 如果需要注销功能(踢下线),可以加一个黑名单,验证服务定时拉取这个黑名单
  3. 服务降级的时候,这一步可以去掉
  4. 相比加密 Cookie,不用依赖 HTTP Cookie,更加灵活,适用更多场景。
  5. 应该尽可能保证 Token 不要太长
  6. 顶多 4、5 个字段就够了
  7. JWT 和 加密 Cookie 一样,如果需要存储的信息太多,还是会让请求有点臃肿
  8. 大部分时候只需要验证身份,没有太多信息存储的需求,JWT
  9. 可以在网关那边统一校验
  10. 跨域