2023-10-26 20:38:31 +00:00
|
|
|
from datetime import datetime, timezone
|
2023-10-30 21:00:55 +00:00
|
|
|
|
2023-10-26 20:38:31 +00:00
|
|
|
import jwt
|
2024-11-01 12:06:21 +00:00
|
|
|
from pydantic import BaseModel
|
2023-10-30 21:00:55 +00:00
|
|
|
|
2024-11-01 12:06:21 +00:00
|
|
|
from auth.exceptions import ExpiredToken, InvalidToken
|
2023-10-26 21:07:35 +00:00
|
|
|
from settings import JWT_ALGORITHM, JWT_SECRET_KEY
|
2024-11-01 12:06:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TokenPayload(BaseModel):
|
|
|
|
user_id: str
|
|
|
|
username: str
|
|
|
|
exp: datetime
|
|
|
|
iat: datetime
|
|
|
|
iss: str
|
2023-10-26 20:38:31 +00:00
|
|
|
|
2021-06-28 09:08:09 +00:00
|
|
|
|
2022-07-21 11:58:50 +00:00
|
|
|
class JWTCodec:
|
2022-09-03 10:50:14 +00:00
|
|
|
@staticmethod
|
2024-11-01 12:06:21 +00:00
|
|
|
def encode(user, exp: datetime) -> str:
|
2022-09-03 10:50:14 +00:00
|
|
|
payload = {
|
2022-10-31 21:25:25 +00:00
|
|
|
"user_id": user.id,
|
2025-05-16 06:23:48 +00:00
|
|
|
"username": user.slug or user.email or user.phone or "",
|
2022-11-23 14:09:35 +00:00
|
|
|
"exp": exp,
|
2022-11-24 14:31:52 +00:00
|
|
|
"iat": datetime.now(tz=timezone.utc),
|
2023-10-30 21:00:55 +00:00
|
|
|
"iss": "discours",
|
2022-09-03 10:50:14 +00:00
|
|
|
}
|
2022-10-23 09:33:28 +00:00
|
|
|
try:
|
2022-10-31 18:38:41 +00:00
|
|
|
return jwt.encode(payload, JWT_SECRET_KEY, JWT_ALGORITHM)
|
2022-10-23 09:33:28 +00:00
|
|
|
except Exception as e:
|
2023-10-30 21:00:55 +00:00
|
|
|
print("[auth.jwtcodec] JWT encode error %r" % e)
|
2021-06-28 09:08:09 +00:00
|
|
|
|
2022-09-03 10:50:14 +00:00
|
|
|
@staticmethod
|
2024-11-01 12:06:21 +00:00
|
|
|
def decode(token: str, verify_exp: bool = True):
|
2023-01-31 06:57:35 +00:00
|
|
|
r = None
|
2023-02-20 16:09:55 +00:00
|
|
|
payload = None
|
2022-10-23 09:33:28 +00:00
|
|
|
try:
|
|
|
|
payload = jwt.decode(
|
|
|
|
token,
|
|
|
|
key=JWT_SECRET_KEY,
|
2022-10-31 19:53:48 +00:00
|
|
|
options={
|
|
|
|
"verify_exp": verify_exp,
|
2022-10-31 21:05:10 +00:00
|
|
|
# "verify_signature": False
|
2022-10-31 19:53:48 +00:00
|
|
|
},
|
2022-10-23 09:33:28 +00:00
|
|
|
algorithms=[JWT_ALGORITHM],
|
2023-10-30 21:00:55 +00:00
|
|
|
issuer="discours",
|
2022-10-23 09:33:28 +00:00
|
|
|
)
|
2022-10-31 18:38:41 +00:00
|
|
|
r = TokenPayload(**payload)
|
2023-10-10 06:35:27 +00:00
|
|
|
# print('[auth.jwtcodec] debug token %r' % r)
|
2022-10-31 18:38:41 +00:00
|
|
|
return r
|
2022-11-13 23:38:06 +00:00
|
|
|
except jwt.InvalidIssuedAtError:
|
2023-10-30 21:00:55 +00:00
|
|
|
print("[auth.jwtcodec] invalid issued at: %r" % payload)
|
2025-05-16 06:23:48 +00:00
|
|
|
raise ExpiredToken("jwt check token issued time")
|
2022-10-31 21:05:10 +00:00
|
|
|
except jwt.ExpiredSignatureError:
|
2023-10-30 21:00:55 +00:00
|
|
|
print("[auth.jwtcodec] expired signature %r" % payload)
|
2025-05-16 06:23:48 +00:00
|
|
|
raise ExpiredToken("jwt check token lifetime")
|
2022-10-31 21:17:00 +00:00
|
|
|
except jwt.InvalidSignatureError:
|
2025-05-16 06:23:48 +00:00
|
|
|
raise InvalidToken("jwt check signature is not valid")
|
|
|
|
except jwt.InvalidTokenError:
|
|
|
|
raise InvalidToken("jwt check token is not valid")
|
|
|
|
except jwt.InvalidKeyError:
|
|
|
|
raise InvalidToken("jwt check key is not valid")
|