py.lib.aw_web_tools

Yohn Y. 2024-02-25 Child:4d3b509e0967

0:06f00ec09030 Go to Latest

py.lib.aw_web_tools/src/aw_web_tools/jwt.py

..init

History
awgur@0 1 # coding: utf-8
awgur@0 2
awgur@0 3 import jwt
awgur@0 4 from datetime import datetime, timedelta
awgur@0 5 from typing import Optional
awgur@0 6
awgur@0 7 JWT_HASH_ALGO = 'HS512'
awgur@0 8
awgur@0 9
awgur@0 10 class JWTError(Exception):
awgur@0 11 pass
awgur@0 12
awgur@0 13
awgur@0 14 class JWTAuthError(JWTError):
awgur@0 15 """\
awgur@0 16 Провалена проверка токена на допустимость по подписи времени или прочее
awgur@0 17 """
awgur@0 18
awgur@0 19
awgur@0 20 class JWTHelper(object):
awgur@0 21 def __init__(self, key: str):
awgur@0 22 self.key = key
awgur@0 23
awgur@0 24 def encode(self, data: dict, timeout: Optional[int] = None) -> str:
awgur@0 25 if timeout is not None:
awgur@0 26 data['exp'] = datetime.utcnow() + timedelta(seconds=timeout)
awgur@0 27
awgur@0 28 return jwt.encode(data, key=self.key, algorithm=JWT_HASH_ALGO)
awgur@0 29
awgur@0 30 def decode(self, token: str, check_timeout: bool = False) -> dict:
awgur@0 31 opts = {
awgur@0 32 'algorithms': [JWT_HASH_ALGO, ]
awgur@0 33 }
awgur@0 34
awgur@0 35 if check_timeout:
awgur@0 36 opts['options'] = {'require': {'exp'}}
awgur@0 37
awgur@0 38 if token is None:
awgur@0 39 raise JWTAuthError('Ключ отсутствует')
awgur@0 40 else:
awgur@0 41 token = token.encode('utf-8')
awgur@0 42
awgur@0 43 try:
awgur@0 44 return jwt.decode(jwt=token, key=self.key, **opts)
awgur@0 45
awgur@0 46 except (jwt.InvalidIssuerError, jwt.InvalidSignatureError, jwt.ExpiredSignatureError) as e:
awgur@0 47 raise JWTAuthError(str(e))
awgur@0 48
awgur@0 49 except jwt.PyJWTError as e:
awgur@0 50 raise JWTError(f'{type(e).__name__}: {e}')
awgur@0 51
awgur@0 52 @classmethod
awgur@0 53 def make_fabric(cls, key: str):
awgur@0 54 def f():
awgur@0 55 return cls(key=key)
awgur@0 56
awgur@0 57 return f