@@ -53,7 +53,17 @@ def encode(claims, key, algorithm=ALGORITHMS.HS256, headers=None, access_token=N
5353 return jws .sign (claims , key , headers = headers , algorithm = algorithm )
5454
5555
56- def decode (token , key , algorithms = None , options = None , audience = None , issuer = None , subject = None , access_token = None ):
56+ def decode (
57+ token ,
58+ key ,
59+ algorithms = None ,
60+ options = None ,
61+ audience = None ,
62+ issuer = None ,
63+ subject = None ,
64+ access_token = None ,
65+ now = None ,
66+ ):
5767 """Verifies a JWT string's signature and validates reserved claims.
5868
5969 Args:
@@ -74,6 +84,7 @@ def decode(token, key, algorithms=None, options=None, audience=None, issuer=None
7484 claim set, then the access_token must be included, and it must match
7585 the "at_hash" claim.
7686 options (dict): A dictionary of options for skipping validation steps.
87+ now (datetime): Current time. If not set, defaults to current system time.
7788
7889 defaults = {
7990 'verify_signature': True,
@@ -162,6 +173,7 @@ def decode(token, key, algorithms=None, options=None, audience=None, issuer=None
162173 algorithm = algorithm ,
163174 access_token = access_token ,
164175 options = defaults ,
176+ now = now ,
165177 )
166178
167179 return claims
@@ -254,7 +266,7 @@ def _validate_iat(claims):
254266 raise JWTClaimsError ("Issued At claim (iat) must be an integer." )
255267
256268
257- def _validate_nbf (claims , leeway = 0 ):
269+ def _validate_nbf (now , claims , leeway = 0 ):
258270 """Validates that the 'nbf' claim is valid.
259271
260272 The "nbf" (not before) claim identifies the time before which the JWT
@@ -266,6 +278,7 @@ def _validate_nbf(claims, leeway=0):
266278 NumericDate value. Use of this claim is OPTIONAL.
267279
268280 Args:
281+ now (datetime): Current time.
269282 claims (dict): The claims dictionary to validate.
270283 leeway (int): The number of seconds of skew that is allowed.
271284 """
@@ -278,13 +291,13 @@ def _validate_nbf(claims, leeway=0):
278291 except ValueError :
279292 raise JWTClaimsError ("Not Before claim (nbf) must be an integer." )
280293
281- now = timegm (datetime . utcnow () .utctimetuple ())
294+ now = timegm (now .utctimetuple ())
282295
283296 if nbf > (now + leeway ):
284297 raise JWTClaimsError ("The token is not yet valid (nbf)" )
285298
286299
287- def _validate_exp (claims , leeway = 0 ):
300+ def _validate_exp (now , claims , leeway = 0 ):
288301 """Validates that the 'exp' claim is valid.
289302
290303 The "exp" (expiration time) claim identifies the expiration time on
@@ -296,6 +309,7 @@ def _validate_exp(claims, leeway=0):
296309 containing a NumericDate value. Use of this claim is OPTIONAL.
297310
298311 Args:
312+ now (datetime): Current time.
299313 claims (dict): The claims dictionary to validate.
300314 leeway (int): The number of seconds of skew that is allowed.
301315 """
@@ -308,7 +322,7 @@ def _validate_exp(claims, leeway=0):
308322 except ValueError :
309323 raise JWTClaimsError ("Expiration Time claim (exp) must be an integer." )
310324
311- now = timegm (datetime . utcnow () .utctimetuple ())
325+ now = timegm (now .utctimetuple ())
312326
313327 if exp < (now - leeway ):
314328 raise ExpiredSignatureError ("Signature has expired." )
@@ -455,7 +469,16 @@ def _validate_at_hash(claims, access_token, algorithm):
455469 raise JWTClaimsError ("at_hash claim does not match access_token." )
456470
457471
458- def _validate_claims (claims , audience = None , issuer = None , subject = None , algorithm = None , access_token = None , options = None ):
472+ def _validate_claims (
473+ claims ,
474+ audience = None ,
475+ issuer = None ,
476+ subject = None ,
477+ algorithm = None ,
478+ access_token = None ,
479+ options = None ,
480+ now = None ,
481+ ):
459482
460483 leeway = options .get ("leeway" , 0 )
461484
@@ -475,10 +498,12 @@ def _validate_claims(claims, audience=None, issuer=None, subject=None, algorithm
475498 _validate_iat (claims )
476499
477500 if options .get ("verify_nbf" ):
478- _validate_nbf (claims , leeway = leeway )
501+ now = now or datetime .utcnow ()
502+ _validate_nbf (now , claims , leeway = leeway )
479503
480504 if options .get ("verify_exp" ):
481- _validate_exp (claims , leeway = leeway )
505+ now = now or datetime .utcnow ()
506+ _validate_exp (now , claims , leeway = leeway )
482507
483508 if options .get ("verify_aud" ):
484509 _validate_aud (claims , audience = audience )
0 commit comments