跳转至

JWT机制

  • 记录用户的登录状态,或者为用户创建身份认证的凭证,我们不再使用Session认证机制,而使用Json Web Token认证机制
  • 服务端不存放用户的各种信息,只在用户访问的时候根据header与pyaload使用我们本地的密钥加密得到signature与客户端的signature进行比对,如果一样说明用户没有修改JWT,如果不同说明用户修改了信息(客户端没有密钥,无法根据header+payload算出signature,我们只比较signature)
  • 基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息
  • token必须要在每次请求时传递给服务端,它应该保存在请求头里,另外,服务端要支持CORS(跨来源资源共享)策略

  • 用户使用用户名密码来请求服务器

  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务器每次在返回客户端数据之前验证token值

JWT构成

  • 注意!!!: secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去(泄漏就GG,谁都可以生成符合你服务器用户的身份)
  • JWT是由三段信息构成的header.payload.signature,这三段信息文本用'.'链接一起就构成了JWT字符串
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
  • header: 包含了声明类型:jwt,加密的算法:HMAC SHA256加密前就像{'typ': 'JWT', 'alg': 'HS256'}这样,通过base64加密(该加密可逆)形成这样的头部eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  • payload: 载荷就是存放有效信息的地方,加密前就是{"sub": "1234567890", "name": "John Doe", "admin": true}通过base64加密(该加密可逆)形成这样的载荷eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
  • signature: 通过加密后的headerandpayload,使用header中声明的加密方式进行加盐secret组合加密

安装

pip install PyJWT

Demo

import jwt
from jwt import PyJWTError
from datetime import datetime, timedelta

# 设置密钥
key = 'XianTanLuoHua'

# 设置payload, 中间接收一个字典
payload = {
    'payload': 'test12345', # 加密内容
    'exp':datetime.utcnow() + timedelta(seconds=12) # 加密时间
}

# 加密得到签名: (payload, 密钥, 加密规则)
token = jwt.encode(payload, key,algorithm='HS256')
print('修改前:', token)

token = (token.decode() + '-->0.0').encode() # 人为修改了数据,下方会校验失败
print('修改后:', token)

# 校验jwt: (token, 密钥, 加密规则)
try:
    payload = jwt.decode(token, key, algorithm='HS256')
    print(payload)
except: # 如果校验失败
    print('校验失败')

Web应用

  • 返回时需要给用户请求头中加入Authorization并加上Bearer标注(注意空格)
headers: {
    ...
    'Authorization': 'Bearer ' + token
    ...
  }