66from flask_jwt_extended .config import config
77from flask_jwt_extended .exceptions import (
88 JWTDecodeError , NoAuthorizationError , InvalidHeaderError , WrongTokenError ,
9- RevokedTokenError , FreshTokenRequired , CSRFError
9+ RevokedTokenError , FreshTokenRequired , CSRFError , UserLoadError
1010)
1111from flask_jwt_extended .default_callbacks import (
1212 default_expired_token_callback , default_user_claims_callback ,
1313 default_user_identity_callback , default_invalid_token_callback ,
14- default_unauthorized_callback ,
15- default_needs_fresh_token_callback ,
16- default_revoked_token_callback
14+ default_unauthorized_callback , default_needs_fresh_token_callback ,
15+ default_revoked_token_callback , default_user_loader_error_callback
1716)
1817from flask_jwt_extended .tokens import (
19- encode_refresh_token , decode_jwt ,
20- encode_access_token
18+ encode_refresh_token , decode_jwt , encode_access_token
2119)
20+ from flask_jwt_extended .utils import get_jwt_identity
2221
2322
2423class JWTManager (object ):
@@ -39,6 +38,8 @@ def __init__(self, app=None):
3938 self ._unauthorized_callback = default_unauthorized_callback
4039 self ._needs_fresh_token_callback = default_needs_fresh_token_callback
4140 self ._revoked_token_callback = default_revoked_token_callback
41+ self ._user_loader_callback = None
42+ self ._user_loader_error_callback = default_user_loader_error_callback
4243
4344 # Register this extension with the flask app now (if it is provided)
4445 if app is not None :
@@ -101,6 +102,14 @@ def handle_revoked_token_error(e):
101102 def handle_fresh_token_required (e ):
102103 return self ._needs_fresh_token_callback ()
103104
105+ @app .errorhandler (UserLoadError )
106+ def handler_user_load_error (e ):
107+ # The identity is already saved before this exception was raised,
108+ # otherwise a different exception would be raised, which is why we
109+ # can safely call get_jwt_identity() here
110+ identity = get_jwt_identity ()
111+ return self ._user_loader_error_callback (identity )
112+
104113 @staticmethod
105114 def _set_default_configuration_options (app ):
106115 """
@@ -244,6 +253,50 @@ def revoked_token_loader(self, callback):
244253 self ._revoked_token_callback = callback
245254 return callback
246255
256+ def user_loader_callback_loader (self , callback ):
257+ """
258+ Sets the callback method to be called to load a user on a protected
259+ endpoint.
260+
261+ By default this is not is not used.
262+
263+ If a callback method is passed in here, it must take one argument,
264+ which is the identity of the user to load. It must return the user
265+ object, or None in the case of an error (which will cause the TODO
266+ error handler to be hit)
267+ """
268+ self ._user_loader_callback = callback
269+ return callback
270+
271+ def user_loader_error_loader (self , callback ):
272+ """
273+ Sets the callback method to be called if a user fails or is refused
274+ to load when calling the _user_loader_callback function (indicated by
275+ that function returning None)
276+
277+ The default implementation will return json:
278+ '{"msg": "Error loading the user <identity>"}' with a 400 status code.
279+
280+ Callback must be a function that takes one argument, the identity of the
281+ user who failed to load.
282+ """
283+ self ._user_loader_error_callback = callback
284+ return callback
285+
286+ def has_user_loader (self ):
287+ """
288+ Returns True if a user_loader_callback has been defined in this
289+ application, False otherwise
290+ """
291+ return self ._user_loader_callback is not None
292+
293+ def user_loader (self , identity ):
294+ """
295+ Calls the _user_loader_callback function (if it is defined) and returns
296+ the resulting user from this callback.
297+ """
298+ return self ._user_loader_callback (identity )
299+
247300 def create_refresh_token (self , identity , expires_delta = None ):
248301 """
249302 Creates a new refresh token
@@ -315,3 +368,4 @@ def create_access_token(self, identity, fresh=False, expires_delta=None):
315368 config .algorithm , csrf = config .csrf_protect )
316369 store_token (decoded_token , revoked = False )
317370 return access_token
371+
0 commit comments