zoukankan      html  css  js  c++  java
  • Python中Jwt

    python

    加密

    pip3 install pyjwt

    import jwt
    import datetime
    from jwt import exceptions
    SALT = 'iv%x6xo7l7_u9bf_u!9#g#m*)*=ej@bek5)(@u3kh*72+unjv='
    def create_token():
        # 构造header
        headers = {
            'typ': 'jwt',
            'alg': 'HS256'
        }
        # 构造payload
        payload = {
            'user_id': 1, # 自定义用户ID
            'username': 'wupeiqi', # 自定义用户名
            'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=5) # 超时时间
        }
        result = jwt.encode(payload=payload, key=SALT, algorithm="HS256", headers=headers).decode('utf-8')
        return result
    if __name__ == '__main__':
        token = create_token()
        print(token)
    

    校验

    对第一部分header_segment进行base64url解密,得到header

    对第二部分payload_segment进行base64url解密,得到payload

    对第三部分crypto_segment进行base64url解密,得到signature

    对第三部分signature部分数据进行合法性校验

    拼接前两段密文,即:signing_input
    从第一段明文中获取加密算法,默认:HS256
    使用 算法+盐 对signing_input 进行加密,将得到的结果和signature密文进行比较

    port jwt
    import datetime
    from jwt import exceptions
    def get_payload(token):
        """
        根据token获取payload
        :param token:
        :return:
        """
        try:
            # 从token中获取payload【不校验合法性】
            # unverified_payload = jwt.decode(token, None, False)
            # print(unverified_payload)
            # 从token中获取payload【校验合法性】
            verified_payload = jwt.decode(token, SALT, True)
            return verified_payload
        except exceptions.ExpiredSignatureError:
            print('token已失效')
        except jwt.DecodeError:
            print('token认证失败')
        except jwt.InvalidTokenError:
            print('非法的token')
    if __name__ == '__main__':
        token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NzM1NTU1NzksInVzZXJuYW1lIjoid3VwZWlxaSIsInVzZXJfaWQiOjF9.xj-7qSts6Yg5Ui55-aUOHJS4KSaeLq5weXMui2IIEJU"
        payload = get_payload(token)
    

    案例

    djangorestframework

    extensions -- auth.py 认证类

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from rest_framework.authentication import BaseAuthentication
    from rest_framework import exceptions
    from utils.jwt_auth import parse_payload
    
    
    
    
    class JwtQueryParamAuthentication(BaseAuthentication):
        """
        用户需要在url中通过参数进行传输token,例如:
        http://www.pythonav.com?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NzM1NTU1NzksInVzZXJuYW1lIjoid3VwZWlxaSIsInVzZXJfaWQiOjF9.xj-7qSts6Yg5Ui55-aUOHJS4KSaeLq5weXMui2IIEJU
        """
    
    
        def authenticate(self, request):
            token = request.query_params.get('token')
            payload = parse_payload(token)
            if not payload['status']:
                raise exceptions.AuthenticationFailed(payload)
    
    
            # 如果想要request.user等于用户对象,此处可以根据payload去数据库中获取用户对象。
            return (payload, token)
    
    
    
    
    class JwtAuthorizationAuthentication(BaseAuthentication):
        """
        用户需要通过请求头的方式来进行传输token,例如:
        Authorization:jwt eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NzM1NTU1NzksInVzZXJuYW1lIjoid3VwZWlxaSIsInVzZXJfaWQiOjF9.xj-7qSts6Yg5Ui55-aUOHJS4KSaeLq5weXMui2IIEJU
        """
    
    
        def authenticate(self, request):
    
    
            # 非登录页面需要校验token
            authorization = request.META.get('HTTP_AUTHORIZATION', '')
            auth = authorization.split()
            if not auth:
                raise exceptions.AuthenticationFailed({'error': '未获取到Authorization请求头', 'status': False})
            if auth[0].lower() != 'jwt':
                raise exceptions.AuthenticationFailed({'error': 'Authorization请求头中认证方式错误', 'status': False})
    
    
            if len(auth) == 1:
                raise exceptions.AuthenticationFailed({'error': "非法Authorization请求头", 'status': False})
            elif len(auth) > 2:
                raise exceptions.AuthenticationFailed({'error': "非法Authorization请求头", 'status': False})
    
    
            token = auth[1]
            result = parse_payload(token)
            if not result['status']:
                raise exceptions.AuthenticationFailed(result)
    
    
            # 如果想要request.user等于用户对象,此处可以根据payload去数据库中获取用户对象。
            return (result, token)
    
    
    

    utils -- jwt_auth.py 生成或验证token

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import jwt
    import datetime
    from jwt import exceptions
    
    
    JWT_SALT = 'iv%x6xo7l7_u9bf_u!9#g#m*)*=ej@bek5)(@u3kh*72+unjv='
    
    
    
    
    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=JWT_SALT, algorithm="HS256", headers=headers).decode('utf-8')
        return result
    
    
    
    
    def parse_payload(token):
        """
        对token进行和发行校验并获取payload
        :param token:
        :return:
        """
        result = {'status': False, 'data': None, 'error': None}
        try:
            verified_payload = jwt.decode(token, JWT_SALT, True)
            result['status'] = True
            result['data'] = verified_payload
        except exceptions.ExpiredSignatureError:
            result['error'] = 'token已失效'
        except jwt.DecodeError:
            result['error'] = 'token认证失败'
        except jwt.InvalidTokenError:
            result['error'] = '非法的token'
        return result
    
  • 相关阅读:
    你不知道的JS
    Git学习攻略
    InteliJ Idea 编写项目常见的问题及解决方案
    上海租房攻略
    JS数组攻略
    Web开发必备的Chrome插件
    BFC和清除浮动
    Angular最新教程-第十一节 路由四 (嵌套路由)
    Angular最新教程-第十节 路由三(路由器钩子函数、路由守卫)
    Angular最新教程-第九节 路由二(路由策略、base标签、路由参数)
  • 原文地址:https://www.cnblogs.com/tangshuo/p/12744268.html
Copyright © 2011-2022 走看看