@@ -170,27 +170,52 @@ def _decode_jwt_from_cookies(request_type):
170
170
return decode_token (encoded_token , csrf_value = csrf_value )
171
171
172
172
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
+
173
182
def _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 :
178
197
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 ])
189
218
190
- # Make sure the type of token we received matches the request type we expect
191
219
verify_token_type (decoded_token , expected_type = request_type )
192
-
193
- # If blacklisting is enabled, see if this token has been revoked
194
220
verify_token_not_blacklisted (decoded_token , request_type )
195
-
196
221
return decoded_token
0 commit comments