44from django .contrib .auth .models import User
55from django .contrib .auth import logout
66from django .db import transaction
7+ from django .core .cache import cache
8+ from django .conf import settings
79from keycloak .exceptions import KeycloakGetError
810
911from cloudharness .auth .exceptions import InvalidToken
1416from psycopg2 .errors import UniqueViolation
1517
1618
19+ USER_CACHE_TTL = getattr (settings , "BEARER_TOKEN_USER_CACHE_TTL" , 60 )
20+
21+
1722def _get_user (kc_user_id : str ) -> User :
1823 """
1924 Get or create a Django user for the given Keycloak user ID.
@@ -108,7 +113,7 @@ def __init__(self, get_response=None):
108113
109114 @transaction .atomic
110115 def __call__ (self , request ):
111- user = getattr ( request , "user" , None )
116+
112117 authentication_token = get_authentication_token ()
113118 if not authentication_token or authentication_token == 'Bearer undefined' :
114119 return self .get_response (request )
@@ -121,6 +126,16 @@ def __call__(self, request):
121126 response .delete_cookie ('kc-access' )
122127 return response
123128
129+ if kc_user_id :
130+ cache_key = f"bearer_token_user:{ kc_user_id } "
131+ cached_user = cache .get (cache_key )
132+ if cached_user :
133+ request .user = cached_user
134+ request ._cached_user = cached_user
135+ return self .get_response (request )
136+
137+ user = getattr (request , "user" , None )
138+
124139 if kc_user :
125140 if not user or user .is_anonymous or getattr (user , "member" , None ) is None or user .member .kc_id != kc_user_id :
126141 user = _get_user (kc_user_id )
@@ -132,6 +147,7 @@ def __call__(self, request):
132147 # Safe to assign - user has a valid Member
133148 request .user = user
134149 request ._cached_user = user
150+
135151 except :
136152 # This should NEVER happen due to _get_user safety checks,
137153 # but if it does, DO NOT assign the user - keep anonymous
@@ -140,7 +156,8 @@ def __call__(self, request):
140156 # Don't assign user - request will remain anonymous
141157 # elif not request.path.startswith('/admin/'):
142158 # logout(request)
143-
159+ if kc_user_id :
160+ cache .set (cache_key , user , timeout = USER_CACHE_TTL )
144161 return self .get_response (request )
145162
146163
0 commit comments