9 jwt
jwt原理:
jwt的生成token格式如下,即:由 . 连接的三段字符串组成。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
生成规则如下:
第一段HEADER部分,固定包含算法和token类型,对此json进行base64url加密,这就是token的第一段。
{
"alg": "HS256",
"typ": "JWT"
}
第二段PAYLOAD部分,包含一些数据,对此json进行base64url加密,这就是token的第二段
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
...
}
第三段SIGNATURE部分,把前两段的base密文通过.拼接起来,然后对其进行HS256加密,再然后对hs256密文进行base64url加密,最终得到token的第三段。
base64url(
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
your-256-bit-secret (秘钥加盐)
)
)
最后将三段字符串通过 . 拼接起来就生成了jwt的token。
注意:base64url加密是先做base64加密,然后再将 -
替代+
及 _
替代 /
。
前后端分离认证有两种方式:
-
基于
token
,drf
案例中的项目。
-
基于
jwt
【推荐】
jwt
的原理是什么呢?
pip install pyjwt
-
生成
jwt token
import jwt import datetime from jwt import exceptions SALT = 'wo*shi*yan' def create_token(): # 构造header headers = { 'typ': 'jwt', 'alg': 'HS256' } # 构造payload payload = { 'user_id': 1, # 自定义用户ID 'username': 'alex', # 自动以用户名 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=5) # 超时时间(当前时间+5分钟) } result = jwt.encode(payload=payload, key=SALT, algorithm='HS256', headers=headers) return result if __name__ == '__main__': token = create_token() print(token) # eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFsZXgiLCJleHAiOjE2NDgxNzkxNTN9.EUbJnf-hzV_rgDQhm4Kc4otRgZLtfsusAET3mkRXOOM
-
校验
import jwt from jwt import exceptions SALT = 'wo*shi*yan' def get_payload(token): """根据token获取payload""" try: # 从token中获取payload【校验合法性,并获取payload】 verified_payload = jwt.decode(token, SALT, ['HS256']) return verified_payload except exceptions.ExpiredSignatureError: print('token已失效') except jwt.DecodeError: print('token认证失败') except jwt.InvalidTokenError: print('非法的token') if __name__ == '__main__': token = 'eyJ0eXAiOiJqd3QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFsZXgiLCJleHAiOjE2NDgxNzkxNTN9.EUbJnf-hzV_rgDQhm4Kc4otRgZLtfsusAET3mkRXOOM' payload = get_payload(token) print(payload) # {'user_id': 1, 'username': 'alex', 'exp': 1648179153}
utils/jwt_auth.py文件
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import jwt
import datetime
from jwt import exceptions
from django.conf import settings
def create_token(payload, timeout=20):
"""
:param payload: 例如:{'user_id':1,'username':'wupeiqi'}用户信息
:param timeout: token的过期时间,默认20分钟
:return:
"""
headers = {
'typ': 'jwt',
'alg': 'HS256'
}
payload['exp'] = datetime.datetime.utcnow() + datetime.timedelta(minutes=timeout)
result = jwt.encode(payload=payload, key=settings.SECRET_KEY.encode('utf-8'), algorithm="HS256", headers=headers)
return result
def parse_payload(token):
"""
对token进行和发行校验并获取payload
:param token:
:return:
"""
try:
verified_payload = jwt.decode(token, settings.SECRET_KEY.encode('utf-8'), algorithms=['HS256'])
return True, verified_payload
except exceptions.ExpiredSignatureError:
error = 'token已失效'
except jwt.DecodeError:
error = 'token认证失败'
except jwt.InvalidTokenError:
error = '非法的token'
return False, error