feat(auth): move JWT blacklist to Redis with TTL [FASE-0.2]

Revoke tokens by jti in a dedicated Redis DB, honor TTL from JWT exp on logout, reject revoked tokens in get_current_user, and add FakeRedis-backed API tests.
This commit is contained in:
2026-05-18 13:19:15 +02:00
parent 9b70655b7e
commit c5eb6f6dc1
5 changed files with 104 additions and 13 deletions

View File

@@ -80,11 +80,11 @@ def blacklist_token(jti: str, exp: float) -> None:
to ``exp - now`` so the key vanishes when the token would have expired
naturally.
"""
from app.infrastructure.redis_client import get_redis
from app.infrastructure.redis_client import get_redis_blacklist
ttl = max(int(exp - datetime.now(timezone.utc).timestamp()), 1)
try:
r = get_redis()
r = get_redis_blacklist()
r.setex(f"{_BLACKLIST_PREFIX}{jti}", ttl, "1")
except Exception:
logger.warning("Failed to blacklist token %s in Redis", jti, exc_info=True)
@@ -92,10 +92,10 @@ def blacklist_token(jti: str, exp: float) -> None:
def is_token_blacklisted(jti: str) -> bool:
"""Return ``True`` if *jti* has been revoked (exists in Redis)."""
from app.infrastructure.redis_client import get_redis
from app.infrastructure.redis_client import get_redis_blacklist
try:
r = get_redis()
r = get_redis_blacklist()
return r.exists(f"{_BLACKLIST_PREFIX}{jti}") > 0
except Exception:
logger.warning("Failed to check blacklist for %s in Redis", jti, exc_info=True)