@@ -170,27 +170,52 @@ def _decode_jwt_from_cookies(request_type):
170170 return decode_token (encoded_token , csrf_value = csrf_value )
171171
172172
173+ def _decode_jwt_from_query_string ():
174+ query_param = config .query_string_name
175+ encoded_token = request .args .get (query_param )
176+ if not encoded_token :
177+ raise NoAuthorizationError ('Missing "{}" query paramater' .format (query_param ))
178+
179+ return decode_token (encoded_token )
180+
181+
173182def _decode_jwt_from_request (request_type ):
174- # We have three cases here, having jwts in both cookies and headers is
175- # valid, or the jwt can only be saved in one of cookies or headers. Check
176- # all cases here.
177- if config .jwt_in_cookies and config .jwt_in_headers :
183+ # All the places we can get a JWT from in this request
184+ decode_functions = []
185+ if config .jwt_in_cookies :
186+ decode_functions .append (lambda : _decode_jwt_from_cookies (request_type ))
187+ if config .jwt_in_query_string :
188+ decode_functions .append (_decode_jwt_from_query_string )
189+ if config .jwt_in_headers :
190+ decode_functions .append (_decode_jwt_from_headers )
191+
192+ # Try to find the token from one of these locations. It only needs to exist
193+ # in one place to be valid (not every location).
194+ errors = []
195+ decoded_token = None
196+ for decode_function in decode_functions :
178197 try :
179- decoded_token = _decode_jwt_from_cookies (request_type )
180- except NoAuthorizationError :
181- try :
182- decoded_token = _decode_jwt_from_headers ()
183- except NoAuthorizationError :
184- raise NoAuthorizationError ("Missing JWT in headers and cookies" )
185- elif config .jwt_in_headers :
186- decoded_token = _decode_jwt_from_headers ()
187- else :
188- decoded_token = _decode_jwt_from_cookies (request_type )
198+ decoded_token = decode_function ()
199+ break
200+ except NoAuthorizationError as e :
201+ errors .append (str (e ))
202+
203+ # Do some work to make a helpful and human readable error message if no
204+ # token was found in any of the expected locations.
205+ if not decoded_token :
206+ token_locations = config .token_location
207+ multiple_jwt_locations = len (token_locations ) != 1
208+
209+ if multiple_jwt_locations :
210+ err_msg = "Missing JWT in {start_locs} or {end_locs} ({details})" .format (
211+ start_locs = ", " .join (token_locations [:- 1 ]),
212+ end_locs = token_locations [- 1 ],
213+ details = "; " .join (errors )
214+ )
215+ raise NoAuthorizationError (err_msg )
216+ else :
217+ raise NoAuthorizationError (errors [0 ])
189218
190- # Make sure the type of token we received matches the request type we expect
191219 verify_token_type (decoded_token , expected_type = request_type )
192-
193- # If blacklisting is enabled, see if this token has been revoked
194220 verify_token_not_blacklisted (decoded_token , request_type )
195-
196221 return decoded_token
0 commit comments