py.lib.aw_web_tools

Yohn Y. 2025-10-15 Parent:b9fd029be707

14:0920ae304dfd Go to Latest

py.lib.aw_web_tools/src/aw_web_tools/jwt_helper.py

.. 1.202510.1 + Режим фековой авторизации для адаптера authelia. Режим требуется для отладки, поскольку вряд ли на машине разработчика будет развёрнуто это ПО на ранних стадиях разработки (преальфа). Возможно режим будет полезен при поиска проблем в приложении при авторизации.

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