@@ -63,7 +63,17 @@ def encode(claims, key, algorithm=ALGORITHMS.HS256, headers=None, access_token=N
6363 return jws .sign (claims , key , headers = headers , algorithm = algorithm )
6464
6565
66- def decode (token , key , algorithms = None , options = None , audience = None , issuer = None , subject = None , access_token = None ):
66+ def decode (
67+ token ,
68+ key ,
69+ algorithms = None ,
70+ options = None ,
71+ audience = None ,
72+ issuer = None ,
73+ subject = None ,
74+ access_token = None ,
75+ now = None ,
76+ ):
6777 """Verifies a JWT string's signature and validates reserved claims.
6878
6979 Args:
@@ -91,6 +101,7 @@ def decode(token, key, algorithms=None, options=None, audience=None, issuer=None
91101 claim set, then the access_token must be included, and it must match
92102 the "at_hash" claim.
93103 options (dict): A dictionary of options for skipping validation steps.
104+ now (datetime): Current time. If not set, defaults to current system time.
94105
95106 defaults = {
96107 'verify_signature': True,
@@ -179,6 +190,7 @@ def decode(token, key, algorithms=None, options=None, audience=None, issuer=None
179190 algorithm = algorithm ,
180191 access_token = access_token ,
181192 options = defaults ,
193+ now = now ,
182194 )
183195
184196 return claims
@@ -271,7 +283,7 @@ def _validate_iat(claims):
271283 raise JWTClaimsError ("Issued At claim (iat) must be an integer." )
272284
273285
274- def _validate_nbf (claims , leeway = 0 ):
286+ def _validate_nbf (now , claims , leeway = 0 ):
275287 """Validates that the 'nbf' claim is valid.
276288
277289 The "nbf" (not before) claim identifies the time before which the JWT
@@ -283,6 +295,7 @@ def _validate_nbf(claims, leeway=0):
283295 NumericDate value. Use of this claim is OPTIONAL.
284296
285297 Args:
298+ now (datetime): Current time.
286299 claims (dict): The claims dictionary to validate.
287300 leeway (int): The number of seconds of skew that is allowed.
288301 """
@@ -295,13 +308,13 @@ def _validate_nbf(claims, leeway=0):
295308 except ValueError :
296309 raise JWTClaimsError ("Not Before claim (nbf) must be an integer." )
297310
298- now = timegm (datetime . now ( UTC ) .utctimetuple ())
311+ now = timegm (now .utctimetuple ())
299312
300313 if nbf > (now + leeway ):
301314 raise JWTClaimsError ("The token is not yet valid (nbf)" )
302315
303316
304- def _validate_exp (claims , leeway = 0 ):
317+ def _validate_exp (now , claims , leeway = 0 ):
305318 """Validates that the 'exp' claim is valid.
306319
307320 The "exp" (expiration time) claim identifies the expiration time on
@@ -313,6 +326,7 @@ def _validate_exp(claims, leeway=0):
313326 containing a NumericDate value. Use of this claim is OPTIONAL.
314327
315328 Args:
329+ now (datetime): Current time.
316330 claims (dict): The claims dictionary to validate.
317331 leeway (int): The number of seconds of skew that is allowed.
318332 """
@@ -325,7 +339,7 @@ def _validate_exp(claims, leeway=0):
325339 except ValueError :
326340 raise JWTClaimsError ("Expiration Time claim (exp) must be an integer." )
327341
328- now = timegm (datetime . now ( UTC ) .utctimetuple ())
342+ now = timegm (now .utctimetuple ())
329343
330344 if exp < (now - leeway ):
331345 raise ExpiredSignatureError ("Signature has expired." )
@@ -472,7 +486,17 @@ def _validate_at_hash(claims, access_token, algorithm):
472486 raise JWTClaimsError ("at_hash claim does not match access_token." )
473487
474488
475- def _validate_claims (claims , audience = None , issuer = None , subject = None , algorithm = None , access_token = None , options = None ):
489+ def _validate_claims (
490+ claims ,
491+ audience = None ,
492+ issuer = None ,
493+ subject = None ,
494+ algorithm = None ,
495+ access_token = None ,
496+ options = None ,
497+ now = None ,
498+ ):
499+
476500 leeway = options .get ("leeway" , 0 )
477501
478502 if isinstance (leeway , timedelta ):
@@ -491,10 +515,12 @@ def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm
491515 _validate_iat (claims )
492516
493517 if options .get ("verify_nbf" ):
494- _validate_nbf (claims , leeway = leeway )
518+ now = now or datetime .now (UTC )
519+ _validate_nbf (now , claims , leeway = leeway )
495520
496521 if options .get ("verify_exp" ):
497- _validate_exp (claims , leeway = leeway )
522+ now = now or datetime .now (UTC )
523+ _validate_exp (now , claims , leeway = leeway )
498524
499525 if options .get ("verify_aud" ):
500526 _validate_aud (claims , audience = audience )
0 commit comments