@@ -35,6 +35,7 @@ class SessionModule(Protocol):
3535 cookie_password : str
3636 jwks : PyJWKClient
3737 jwk_algorithms : List [str ]
38+ jwt_leeway : float
3839
3940 def __init__ (
4041 self ,
@@ -43,6 +44,7 @@ def __init__(
4344 client_id : str ,
4445 session_data : str ,
4546 cookie_password : str ,
47+ jwt_leeway : float = 0 ,
4648 ) -> None :
4749 # If the cookie password is not provided, throw an error
4850 if cookie_password is None or cookie_password == "" :
@@ -52,6 +54,7 @@ def __init__(
5254 self .client_id = client_id
5355 self .session_data = session_data
5456 self .cookie_password = cookie_password
57+ self .jwt_leeway = jwt_leeway
5558
5659 self .jwks = _get_jwks_client (self .user_management .get_jwks_url ())
5760
@@ -91,13 +94,13 @@ def authenticate(
9194 signing_key .key ,
9295 algorithms = self .jwk_algorithms ,
9396 options = {"verify_aud" : False },
97+ leeway = self .jwt_leeway ,
9498 )
9599 except jwt .exceptions .InvalidTokenError :
96100 return AuthenticateWithSessionCookieErrorResponse (
97101 authenticated = False ,
98102 reason = AuthenticateWithSessionCookieFailureReason .INVALID_JWT ,
99103 )
100-
101104 return AuthenticateWithSessionCookieSuccessResponse (
102105 authenticated = True ,
103106 session_id = decoded ["sid" ],
@@ -137,6 +140,20 @@ def get_logout_url(self, return_to: Optional[str] = None) -> str:
137140 )
138141 return str (result )
139142
143+ def _is_valid_jwt (self , token : str ) -> bool :
144+ try :
145+ signing_key = self .jwks .get_signing_key_from_jwt (token )
146+ jwt .decode (
147+ token ,
148+ signing_key .key ,
149+ algorithms = self .jwk_algorithms ,
150+ options = {"verify_aud" : False },
151+ leeway = self .jwt_leeway ,
152+ )
153+ return True
154+ except jwt .exceptions .InvalidTokenError :
155+ return False
156+
140157 @staticmethod
141158 def seal_data (data : Dict [str , Any ], key : str ) -> str :
142159 fernet = Fernet (key )
@@ -163,6 +180,7 @@ def __init__(
163180 client_id : str ,
164181 session_data : str ,
165182 cookie_password : str ,
183+ jwt_leeway : float = 0 ,
166184 ) -> None :
167185 # If the cookie password is not provided, throw an error
168186 if cookie_password is None or cookie_password == "" :
@@ -172,6 +190,7 @@ def __init__(
172190 self .client_id = client_id
173191 self .session_data = session_data
174192 self .cookie_password = cookie_password
193+ self .jwt_leeway = jwt_leeway
175194
176195 self .jwks = _get_jwks_client (self .user_management .get_jwks_url ())
177196
@@ -224,6 +243,7 @@ def refresh(
224243 signing_key .key ,
225244 algorithms = self .jwk_algorithms ,
226245 options = {"verify_aud" : False },
246+ leeway = self .jwt_leeway ,
227247 )
228248
229249 return RefreshWithSessionCookieSuccessResponse (
@@ -255,6 +275,7 @@ def __init__(
255275 client_id : str ,
256276 session_data : str ,
257277 cookie_password : str ,
278+ jwt_leeway : float = 0 ,
258279 ) -> None :
259280 # If the cookie password is not provided, throw an error
260281 if cookie_password is None or cookie_password == "" :
@@ -264,6 +285,7 @@ def __init__(
264285 self .client_id = client_id
265286 self .session_data = session_data
266287 self .cookie_password = cookie_password
288+ self .jwt_leeway = jwt_leeway
267289
268290 self .jwks = _get_jwks_client (self .user_management .get_jwks_url ())
269291
@@ -316,6 +338,7 @@ async def refresh(
316338 signing_key .key ,
317339 algorithms = self .jwk_algorithms ,
318340 options = {"verify_aud" : False },
341+ leeway = self .jwt_leeway ,
319342 )
320343
321344 return RefreshWithSessionCookieSuccessResponse (
0 commit comments