py.lib.aw_web_tools
2024-11-03
Parent:src/aw_web_tools/jwt.py@4d3b509e0967
py.lib.aw_web_tools/src/aw_web_tools/jwt_helper.py
.. 1.202411.1 . Переделываем под новые веяния SDK * Рефакторинг
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/aw_web_tools/jwt_helper.py Sun Nov 03 19:25:24 2024 +0300 1.3 @@ -0,0 +1,59 @@ 1.4 +# coding: utf-8 1.5 + 1.6 +import jwt 1.7 +from datetime import datetime, timedelta 1.8 +from typing import Optional 1.9 + 1.10 +from . import Error 1.11 + 1.12 +JWT_HASH_ALGO = 'HS512' 1.13 + 1.14 + 1.15 +class JWTError(Error): 1.16 + pass 1.17 + 1.18 + 1.19 +class JWTAuthError(JWTError): 1.20 + """\ 1.21 + Провалена проверка токена на допустимость по подписи, времени действия или прочее 1.22 + """ 1.23 + 1.24 + 1.25 +class JWTHelper(object): 1.26 + def __init__(self, key: str): 1.27 + self.key = key 1.28 + 1.29 + def encode(self, data: dict, timeout: Optional[int] = None) -> str: 1.30 + if timeout is not None: 1.31 + data['exp'] = datetime.utcnow() + timedelta(seconds=timeout) 1.32 + 1.33 + return jwt.encode(data, key=self.key, algorithm=JWT_HASH_ALGO) 1.34 + 1.35 + def decode(self, token: str, check_timeout: bool = False) -> dict: 1.36 + opts = { 1.37 + 'algorithms': [JWT_HASH_ALGO, ] 1.38 + } 1.39 + 1.40 + if check_timeout: 1.41 + opts['options'] = {'require': {'exp'}} 1.42 + 1.43 + if token is None: 1.44 + raise JWTAuthError('Ключ отсутствует') 1.45 + else: 1.46 + token = token.encode('utf-8') 1.47 + 1.48 + try: 1.49 + return jwt.decode(jwt=token, key=self.key, **opts) 1.50 + 1.51 + except (jwt.InvalidIssuerError, jwt.InvalidSignatureError, jwt.ExpiredSignatureError) as e: 1.52 + raise JWTAuthError(str(e)) 1.53 + 1.54 + except jwt.PyJWTError as e: 1.55 + raise JWTError(f'{type(e).__name__}: {e}') 1.56 + 1.57 + @classmethod 1.58 + def make_fabric(cls, key: str): 1.59 + def f(): 1.60 + return cls(key=key) 1.61 + 1.62 + return f