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加密,然后再将 -替代+_ 替代 /


前后端分离认证有两种方式:

  • 基于tokendrf案例中的项目。
    image

  • 基于jwt【推荐】

    image

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

posted @ 2022-09-28 15:07  角角边  Views(66)  Comments(0Edit  收藏  举报