99from jwt .api_jwt import PyJWT
1010from jwt .exceptions import (
1111 DecodeError , ExpiredSignatureError , ImmatureSignatureError ,
12- InvalidAudienceError , InvalidIssuedAtError , InvalidIssuerError
12+ InvalidAudienceError , InvalidIssuedAtError , InvalidIssuerError ,
13+ MissingRequiredClaimError
1314)
1415
1516import pytest
@@ -317,15 +318,31 @@ def test_raise_exception_invalid_audience_in_array(self, jwt):
317318 with pytest .raises (InvalidAudienceError ):
318319 jwt .decode (token , 'secret' , audience = 'urn:me' )
319320
321+ def test_raise_exception_token_without_issuer (self , jwt ):
322+ issuer = 'urn:wrong'
323+
324+ payload = {
325+ 'some' : 'payload'
326+ }
327+
328+ token = jwt .encode (payload , 'secret' )
329+
330+ with pytest .raises (MissingRequiredClaimError ) as exc :
331+ jwt .decode (token , 'secret' , issuer = issuer )
332+
333+ assert exc .value .claim == 'iss'
334+
320335 def test_raise_exception_token_without_audience (self , jwt ):
321336 payload = {
322337 'some' : 'payload' ,
323338 }
324339 token = jwt .encode (payload , 'secret' )
325340
326- with pytest .raises (InvalidAudienceError ) :
341+ with pytest .raises (MissingRequiredClaimError ) as exc :
327342 jwt .decode (token , 'secret' , audience = 'urn:me' )
328343
344+ assert exc .value .claim == 'aud'
345+
329346 def test_check_issuer_when_valid (self , jwt ):
330347 issuer = 'urn:foo'
331348 payload = {
@@ -348,33 +365,57 @@ def test_raise_exception_invalid_issuer(self, jwt):
348365 with pytest .raises (InvalidIssuerError ):
349366 jwt .decode (token , 'secret' , issuer = issuer )
350367
351- def test_raise_exception_token_without_issuer (self , jwt ):
352- issuer = 'urn:wrong'
368+ def test_skip_check_audience (self , jwt ):
369+ payload = {
370+ 'some' : 'payload' ,
371+ 'aud' : 'urn:me' ,
372+ }
373+ token = jwt .encode (payload , 'secret' )
374+ jwt .decode (token , 'secret' , options = {'verify_aud' : False })
353375
376+ def test_skip_check_exp (self , jwt ):
354377 payload = {
355378 'some' : 'payload' ,
379+ 'exp' : datetime .utcnow () - timedelta (days = 1 )
356380 }
381+ token = jwt .encode (payload , 'secret' )
382+ jwt .decode (token , 'secret' , options = {'verify_exp' : False })
357383
384+ def test_decode_should_raise_error_if_exp_required_but_not_present (self , jwt ):
385+ payload = {
386+ 'some' : 'payload' ,
387+ # exp not present
388+ }
358389 token = jwt .encode (payload , 'secret' )
359390
360- with pytest .raises (InvalidIssuerError ) :
361- jwt .decode (token , 'secret' , issuer = issuer )
391+ with pytest .raises (MissingRequiredClaimError ) as exc :
392+ jwt .decode (token , 'secret' , options = { 'require_exp' : True } )
362393
363- def test_skip_check_audience (self , jwt ):
394+ assert exc .value .claim == 'exp'
395+
396+ def test_decode_should_raise_error_if_iat_required_but_not_present (self , jwt ):
364397 payload = {
365398 'some' : 'payload' ,
366- 'aud' : 'urn:me' ,
399+ # iat not present
367400 }
368401 token = jwt .encode (payload , 'secret' )
369- jwt .decode (token , 'secret' , options = {'verify_aud' : False })
370402
371- def test_skip_check_exp (self , jwt ):
403+ with pytest .raises (MissingRequiredClaimError ) as exc :
404+ jwt .decode (token , 'secret' , options = {'require_iat' : True })
405+
406+ assert exc .value .claim == 'iat'
407+
408+ def test_decode_should_raise_error_if_nbf_required_but_not_present (self , jwt ):
372409 payload = {
373410 'some' : 'payload' ,
374- 'exp' : datetime . utcnow () - timedelta ( days = 1 )
411+ # nbf not present
375412 }
376413 token = jwt .encode (payload , 'secret' )
377- jwt .decode (token , 'secret' , options = {'verify_exp' : False })
414+
415+ with pytest .raises (MissingRequiredClaimError ) as exc :
416+ jwt .decode (token , 'secret' , options = {'require_nbf' : True })
417+
418+ assert exc .value .claim == 'nbf'
378419
379420 def test_skip_check_signature (self , jwt ):
380421 token = ("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
0 commit comments