1+ import hashlib
12from typing import Any , Callable , Dict , List , Optional , cast
23
34import structlog
45from django .conf import settings
56from django .contrib .auth .models import AnonymousUser
7+ from django .core .cache import cache
68from django .db import transaction
79from django .http import HttpRequest , HttpResponse
810from django .utils .functional import SimpleLazyObject
1618
1719logger = structlog .getLogger (__name__ )
1820
21+ TOKEN_CACHE_TTL = 60 * 5 # 5 minutes
22+
23+
24+ def _get_token_cache_key (token : str ) -> str :
25+ """Return a safe Redis key derived from the token without storing the raw token."""
26+ token_hash = hashlib .sha256 (token .encode ()).hexdigest ()
27+ return f"auth_token:{ token_hash } "
28+
1929
2030def get_user_from_keycloak_token (request : HttpRequest ) -> User :
2131 """
@@ -59,6 +69,17 @@ def get_user_from_keycloak_token(request: HttpRequest) -> User:
5969 logger .debug ("No token found, returning anonymous user" )
6070 return cast (User , AnonymousUser ())
6171
72+ # Check cache before doing any validation or DB work
73+ cache_key = _get_token_cache_key (token )
74+ cached_user_id = cache .get (cache_key )
75+ if cached_user_id :
76+ try :
77+ user = User .objects .get (id = cached_user_id )
78+ logger .debug (f"Returning cached authenticated user: { user .username } " )
79+ return user
80+ except User .DoesNotExist :
81+ cache .delete (cache_key )
82+
6283 # Log token details for debugging
6384 logger .debug (f"Processing token of length: { len (token )} " )
6485 logger .debug (f"Token type: { type (token )} " )
@@ -80,6 +101,7 @@ def get_user_from_keycloak_token(request: HttpRequest) -> User:
80101 logger .debug (f"Valid Django JWT token for user_id: { user_id } " )
81102 try :
82103 user = User .objects .get (id = user_id )
104+ cache .set (cache_key , user .id , timeout = TOKEN_CACHE_TTL )
83105 logger .debug (f"Successfully authenticated user via Django JWT: { user .username } " )
84106 return user
85107 except User .DoesNotExist :
@@ -130,6 +152,7 @@ def get_user_from_keycloak_token(request: HttpRequest) -> User:
130152 logger .warning ("User synchronization failed, returning anonymous user" )
131153 return cast (User , AnonymousUser ())
132154
155+ cache .set (cache_key , synced_user .id , timeout = TOKEN_CACHE_TTL )
133156 logger .debug (
134157 f"Successfully authenticated user: { synced_user .username } (ID: { synced_user .id } )"
135158 )
0 commit comments