jwt_service.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. """
  2. JWT Service for token generation and validation.
  3. Handles creation and verification of access and refresh tokens.
  4. """
  5. from datetime import datetime, timedelta
  6. from typing import Dict, Optional
  7. import jwt
  8. from config import settings
  9. class JWTService:
  10. """Service for JWT token operations."""
  11. @staticmethod
  12. def create_access_token(user_data: Dict) -> str:
  13. """
  14. Create access token with 15 minutes expiration.
  15. Args:
  16. user_data: Dict containing user_id, username, email, role
  17. Returns:
  18. Encoded JWT token string
  19. """
  20. expire = datetime.utcnow() + timedelta(
  21. minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES
  22. )
  23. payload = {
  24. "sub": user_data["id"],
  25. "username": user_data["username"],
  26. "email": user_data["email"],
  27. "role": user_data["role"],
  28. "exp": expire,
  29. "iat": datetime.utcnow(),
  30. "type": "access"
  31. }
  32. return jwt.encode(
  33. payload,
  34. settings.JWT_SECRET_KEY,
  35. algorithm=settings.JWT_ALGORITHM
  36. )
  37. @staticmethod
  38. def create_refresh_token(user_data: Dict) -> str:
  39. """
  40. Create refresh token with 7 days expiration.
  41. Args:
  42. user_data: Dict containing user_id
  43. Returns:
  44. Encoded JWT token string
  45. """
  46. expire = datetime.utcnow() + timedelta(
  47. days=settings.REFRESH_TOKEN_EXPIRE_DAYS
  48. )
  49. payload = {
  50. "sub": user_data["id"],
  51. "exp": expire,
  52. "iat": datetime.utcnow(),
  53. "type": "refresh"
  54. }
  55. return jwt.encode(
  56. payload,
  57. settings.JWT_SECRET_KEY,
  58. algorithm=settings.JWT_ALGORITHM
  59. )
  60. @staticmethod
  61. def verify_token(token: str, token_type: str = "access") -> Optional[Dict]:
  62. """
  63. Verify and decode JWT token.
  64. Args:
  65. token: JWT token string
  66. token_type: Expected token type (access or refresh)
  67. Returns:
  68. Decoded payload dict or None if invalid
  69. Raises:
  70. jwt.ExpiredSignatureError: Token has expired
  71. jwt.InvalidTokenError: Token is invalid
  72. """
  73. try:
  74. payload = jwt.decode(
  75. token,
  76. settings.JWT_SECRET_KEY,
  77. algorithms=[settings.JWT_ALGORITHM]
  78. )
  79. # Verify token type
  80. if payload.get("type") != token_type:
  81. return None
  82. return payload
  83. except jwt.ExpiredSignatureError:
  84. raise
  85. except jwt.InvalidTokenError:
  86. raise