@@ -160,6 +160,24 @@ def test_session_cookies(api_key):
160160 estimated_exp = int (time .time () + expires_in .total_seconds ())
161161 assert abs (claims ['exp' ] - estimated_exp ) < 5
162162
163+ def test_session_cookies_with_tolerance (api_key ):
164+ dev_claims = {'premium' : True , 'subscription' : 'silver' }
165+ custom_token = auth .create_custom_token ('user3' , dev_claims )
166+ id_token = _sign_in (custom_token , api_key )
167+ expires_in = datetime .timedelta (seconds = 1 )
168+ session_cookie = auth .create_session_cookie (id_token , expires_in = expires_in )
169+ time .sleep (2 )
170+ # expect this to fail because the cookie is expired
171+ with pytest .raises (auth .ExpiredSessionCookieError ):
172+ auth .verify_session_cookie (session_cookie )
173+
174+ # expect this to succeed because we're within the tolerance
175+ claims = auth .verify_session_cookie (session_cookie , check_revoked = False , tolerance = 2 )
176+ assert claims ['uid' ] == 'user3'
177+ assert claims ['premium' ] is True
178+ assert claims ['subscription' ] == 'silver'
179+ assert claims ['iss' ].startswith ('https://session.firebase.google.com' )
180+
163181def test_session_cookie_error ():
164182 expires_in = datetime .timedelta (days = 1 )
165183 with pytest .raises (auth .InvalidIdTokenError ):
@@ -577,6 +595,22 @@ def test_verify_id_token_revoked(new_user, api_key):
577595 claims = auth .verify_id_token (id_token , check_revoked = True )
578596 assert claims ['iat' ] * 1000 >= user .tokens_valid_after_timestamp
579597
598+ def test_verify_id_token_tolerance (new_user , api_key ):
599+ # create token that expires in 1 second.
600+ custom_token = auth .create_custom_token (new_user .uid , expires_in = datetime .timedelta (seconds = 1 ))
601+ id_token = _sign_in (custom_token , api_key )
602+ time .sleep (1 )
603+
604+ # verify with tolerance of 0 seconds. This should fail.
605+ with pytest .raises (auth .ExpiredIdTokenError ) as excinfo :
606+ auth .verify_id_token (id_token , check_revoked = False , max_age = datetime .timedelta (seconds = 0 ))
607+ assert str (excinfo .value ) == 'The Firebase ID token has expired.'
608+
609+ # verify with tolerance of 2 seconds. This should succeed.
610+ claims = auth .verify_id_token (id_token , check_revoked = False , max_age = datetime .timedelta (seconds = 2 ))
611+ assert claims ['sub' ] == new_user .uid
612+
613+
580614def test_verify_id_token_disabled (new_user , api_key ):
581615 custom_token = auth .create_custom_token (new_user .uid )
582616 id_token = _sign_in (custom_token , api_key )
@@ -617,6 +651,19 @@ def test_verify_session_cookie_revoked(new_user, api_key):
617651 claims = auth .verify_session_cookie (session_cookie , check_revoked = True )
618652 assert claims ['iat' ] * 1000 >= user .tokens_valid_after_timestamp
619653
654+ def test_verify_session_cookie_tolerance (new_user , api_key ):
655+ expired_session_cookie = auth .create_session_cookie (_sign_in (auth .create_custom_token (new_user .uid ), api_key ), expires_in = datetime .timedelta (seconds = 1 ))
656+ time .sleep (1 )
657+ # Verify the session cookie with a tolerance of 0 seconds. This should
658+ # raise an exception because the cookie is expired.
659+ with pytest .raises (auth .InvalidSessionCookieError ) as excinfo :
660+ auth .verify_session_cookie (expired_session_cookie , check_revoked = False , clock_skew_in_seconds = 0 )
661+ assert str (excinfo .value ) == 'The Firebase session cookie is expired.'
662+
663+ # Verify the session cookie with a tolerance of 2 seconds. This should
664+ # not raise an exception because the cookie is within the tolerance.
665+ auth .verify_session_cookie (expired_session_cookie , check_revoked = False , clock_skew_in_seconds = 2 )
666+
620667def test_verify_session_cookie_disabled (new_user , api_key ):
621668 custom_token = auth .create_custom_token (new_user .uid )
622669 id_token = _sign_in (custom_token , api_key )
0 commit comments