diff --git a/docs/options.rst b/docs/options.rst index 3ee6aca1..8d7d75a2 100644 --- a/docs/options.rst +++ b/docs/options.rst @@ -142,6 +142,13 @@ General Options: Default: ``None`` +.. py:data:: JWT_ENCODE_NBF + + The not before (``nbf``) claim which defines that a JWT MUST NOT be accepted for processing during decode. + + Default: ``True`` + + .. py:data:: JWT_DECODE_LEEWAY The number of seconds a token will be considered valid before the Not Before diff --git a/flask_jwt_extended/config.py b/flask_jwt_extended/config.py index b7ab98ed..25f046e9 100644 --- a/flask_jwt_extended/config.py +++ b/flask_jwt_extended/config.py @@ -291,5 +291,9 @@ def decode_issuer(self): def leeway(self): return current_app.config["JWT_DECODE_LEEWAY"] + @property + def encode_nbf(self): + return current_app.config["JWT_ENCODE_NBF"] + config = _Config() diff --git a/flask_jwt_extended/jwt_manager.py b/flask_jwt_extended/jwt_manager.py index b13fff21..c4657cfe 100644 --- a/flask_jwt_extended/jwt_manager.py +++ b/flask_jwt_extended/jwt_manager.py @@ -202,6 +202,7 @@ def _set_default_configuration_options(app): app.config.setdefault("JWT_SECRET_KEY", None) app.config.setdefault("JWT_SESSION_COOKIE", True) app.config.setdefault("JWT_TOKEN_LOCATION", ("headers",)) + app.config.setdefault("JWT_ENCODE_NBF", True) def additional_claims_loader(self, callback): """ @@ -499,6 +500,7 @@ def _encode_jwt_from_config( json_encoder=config.json_encoder, secret=self._encode_key_callback(identity), token_type=token_type, + nbf=config.encode_nbf, ) def _decode_jwt_from_config( diff --git a/flask_jwt_extended/tokens.py b/flask_jwt_extended/tokens.py index 3fcfa473..a21a53d3 100644 --- a/flask_jwt_extended/tokens.py +++ b/flask_jwt_extended/tokens.py @@ -24,6 +24,7 @@ def _encode_jwt( json_encoder, secret, token_type, + nbf, ): now = datetime.now(timezone.utc) @@ -34,11 +35,13 @@ def _encode_jwt( "fresh": fresh, "iat": now, "jti": str(uuid.uuid4()), - "nbf": now, "type": token_type, identity_claim_key: identity, } + if nbf: + token_data["nbf"] = now + if csrf: token_data["csrf"] = str(uuid.uuid4()) diff --git a/tests/test_decode_tokens.py b/tests/test_decode_tokens.py index 8c1f0e5f..6c98e4f6 100644 --- a/tests/test_decode_tokens.py +++ b/tests/test_decode_tokens.py @@ -350,3 +350,18 @@ def test_token_expires_time(app): # the tokens are created assert (access_timestamp - (now_timestamp + 3600)) < 2 assert (refresh_timestamp - (now_timestamp + 7200)) < 2 + + +def test_nbf_is_present_by_default(app): + with app.test_request_context(): + access_token = create_access_token("username", fresh=True) + decoded = decode_token(access_token) + assert "nbf" in decoded + + +def test_disable_nbf_encoding(app): + app.config["JWT_ENCODE_NBF"] = False + with app.test_request_context(): + access_token = create_access_token("username", fresh=True) + decoded = decode_token(access_token) + assert "nbf" not in decoded