diff --git a/docs/options.rst b/docs/options.rst index ffd3700b..f7b6a530 100644 --- a/docs/options.rst +++ b/docs/options.rst @@ -41,6 +41,9 @@ General Options: Defaults to ``'user_claims'``. ``JWT_CLAIMS_IN_REFRESH_TOKEN`` If user claims should be included in refresh tokens. Defaults to ``False``. +``JWT_ERROR_MESSAGE_KEY`` The key of the error message in a JSON error response when using + the default error handlers. + Defaults to ``'msg'``. ================================= ========================================= diff --git a/flask_jwt_extended/config.py b/flask_jwt_extended/config.py index 9d71f492..0a04b24c 100644 --- a/flask_jwt_extended/config.py +++ b/flask_jwt_extended/config.py @@ -255,6 +255,10 @@ def user_claims_in_refresh_token(self): def exempt_methods(self): return {"OPTIONS"} + @property + def error_msg_key(self): + return current_app.config['JWT_ERROR_MESSAGE_KEY'] + @property def json_encoder(self): return current_app.json_encoder diff --git a/flask_jwt_extended/default_callbacks.py b/flask_jwt_extended/default_callbacks.py index c6d31826..972a834f 100644 --- a/flask_jwt_extended/default_callbacks.py +++ b/flask_jwt_extended/default_callbacks.py @@ -8,6 +8,8 @@ """ from flask import jsonify +from flask_jwt_extended.config import config + def default_user_claims_callback(userdata): """ @@ -37,7 +39,7 @@ def default_expired_token_callback(): By default, if an expired token attempts to access a protected endpoint, we return a generic error message with a 401 status """ - return jsonify({'msg': 'Token has expired'}), 401 + return jsonify({config.error_msg_key: 'Token has expired'}), 401 def default_invalid_token_callback(error_string): @@ -47,7 +49,7 @@ def default_invalid_token_callback(error_string): :param error_string: String indicating why the token is invalid """ - return jsonify({'msg': error_string}), 422 + return jsonify({config.error_msg_key: error_string}), 422 def default_unauthorized_callback(error_string): @@ -57,7 +59,7 @@ def default_unauthorized_callback(error_string): :param error_string: String indicating why this request is unauthorized """ - return jsonify({'msg': error_string}), 401 + return jsonify({config.error_msg_key: error_string}), 401 def default_needs_fresh_token_callback(): @@ -65,7 +67,7 @@ def default_needs_fresh_token_callback(): By default, if a non-fresh jwt is used to access a ```fresh_jwt_required``` endpoint, we return a general error message with a 401 status code """ - return jsonify({'msg': 'Fresh token required'}), 401 + return jsonify({config.error_msg_key: 'Fresh token required'}), 401 def default_revoked_token_callback(): @@ -73,7 +75,7 @@ def default_revoked_token_callback(): By default, if a revoked token is used to access a protected endpoint, we return a general error message with a 401 status code """ - return jsonify({'msg': 'Token has been revoked'}), 401 + return jsonify({config.error_msg_key: 'Token has been revoked'}), 401 def default_user_loader_error_callback(identity): @@ -82,7 +84,7 @@ def default_user_loader_error_callback(identity): function returns None, we return a general error message with a 401 status code """ - return jsonify({'msg': "Error loading the user {}".format(identity)}), 401 + return jsonify({config.error_msg_key: "Error loading the user {}".format(identity)}), 401 def default_claims_verification_callback(user_claims): @@ -97,4 +99,4 @@ def default_claims_verification_failed_callback(): By default, if the user claims verification failed, we return a generic error message with a 400 status code """ - return jsonify({'msg': 'User claims verification failed'}), 400 + return jsonify({config.error_msg_key: 'User claims verification failed'}), 400 diff --git a/flask_jwt_extended/jwt_manager.py b/flask_jwt_extended/jwt_manager.py index 586400e8..d94f8d2f 100644 --- a/flask_jwt_extended/jwt_manager.py +++ b/flask_jwt_extended/jwt_manager.py @@ -189,6 +189,8 @@ def _set_default_configuration_options(app): app.config.setdefault('JWT_CLAIMS_IN_REFRESH_TOKEN', False) + app.config.setdefault('JWT_ERROR_MESSAGE_KEY', 'msg') + def user_claims_loader(self, callback): """ This decorator sets the callback function for adding custom claims to an diff --git a/tests/test_config.py b/tests/test_config.py index e1ef5ccf..b3152427 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -65,6 +65,8 @@ def test_default_configs(app): assert config.json_encoder is app.json_encoder + assert config.error_msg_key == 'msg' + def test_override_configs(app): app.config['JWT_TOKEN_LOCATION'] = ['cookies', 'query_string'] @@ -104,6 +106,8 @@ def test_override_configs(app): app.config['JWT_CLAIMS_IN_REFRESH_TOKEN'] = True + app.config['JWT_ERROR_MESSAGE_KEY'] = 'message' + class CustomJSONEncoder(JSONEncoder): pass @@ -156,6 +160,8 @@ class CustomJSONEncoder(JSONEncoder): assert config.json_encoder is CustomJSONEncoder + assert config.error_msg_key == 'message' + def test_tokens_never_expire(app): app.config['JWT_ACCESS_TOKEN_EXPIRES'] = False diff --git a/tests/test_headers.py b/tests/test_headers.py index c9f94094..cf931962 100644 --- a/tests/test_headers.py +++ b/tests/test_headers.py @@ -90,3 +90,9 @@ def custom_response(err_str): response = test_client.get('/protected', headers=None) assert response.status_code == 201 assert response.get_json() == {'foo': "bar"} + + +def test_custom_error_msg_key(app): + app.config['JWT_ERROR_MESSAGE_KEY'] = 'message' + response = app.test_client().get('/protected', headers=None) + assert response.get_json() == {'message': 'Missing Authorization Header'}