Open
Description
Hello,
Following issue #99 I have tried to use a custom header name to get the JWT token.
When we use your module as a classical way (without custom header name) it works perfectly.
When we tried to use a custom header, something breaks, we have an error at each query:
Code:
class CustomAuth(JWTAuthentication):
def get_header(self, request):
header = request.META.get('HTTP_X_AUTHORIZATION')
return header
Settings:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'utils.CustomAuth'
),
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': datetime.timedelta(minutes=60),
'REFRESH_TOKEN_LIFETIME': datetime.timedelta(days=7),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUTH_HEADER_TYPES': ('JWT', 'Bearer', 'Basic'),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': datetime.timedelta(minutes=60),
'SLIDING_TOKEN_REFRESH_LIFETIME': datetime.timedelta(days=7),
}
TypeError
which occurs at each query:
TypeError at route
'type' object is not iterable
Request Method: POST
Request URL: route
Django Version: 2.0.9
Exception Type: TypeError
Exception Value:
'type' object is not iterable
Exception Location: lib/python3.5/site-packages/rest_framework/views.py in get_authenticators, line 274
Python Executable: bin/python
Python Version: 3.5.2
Python Path:
[
'lib/python35.zip',
'lib/python3.5',
'lib/python3.5/plat-x86_64-linux-gnu',
'lib/python3.5/lib-dynload',
'/usr/lib/python3.5',
'/usr/lib/python3.5/plat-x86_64-linux-gnu',
'lib/python3.5/site-packages']
Server time: Mon, 8 Jul 2019 09:38:19 +0000
Traceback Switch to copy-and-paste view
lib/python3.5/site-packages/django/core/handlers/exception.py in inner
This decorator is automatically applied to all middleware to ensure that
no middleware leaks an exception and that the next middleware in the stack
can rely on getting a response instead of an exception.
"""
@wraps(get_response)
def inner(request):
try:
response = get_response(request) ...
except Exception as exc:
response = response_for_exception(request, exc)
return response
return inner
▶ Local vars
Variable Value
exc
TypeError("'type' object is not iterable",)
get_response
<bound method BaseHandler._get_response of <django.core.handlers.wsgi.WSGIHandler object at 0x7fe2ca54a9b0>>
request
<WSGIRequest: POST 'route'>
lib/python3.5/site-packages/django/core/handlers/base.py in _get_response
break
if response is None:
wrapped_callback = self.make_view_atomic(callback)
try:
response = wrapped_callback(request, *callback_args, **callback_kwargs)
except Exception as e:
response = self.process_exception_by_middleware(e, request) ...
# Complain if the view returned None (a common error).
if response is None:
if isinstance(callback, types.FunctionType): # FBV
view_name = callback.__name__
else: # CBV
▶ Local vars
Variable Value
callback
<function WrappedAPIView at 0x7fe2ca7eee18>
callback_args
()
callback_kwargs
{}
middleware_method
<bound method DebugToolbarMiddleware.process_view of <debug_toolbar.middleware.DebugToolbarMiddleware object at 0x7fe2ca555048>>
request
<WSGIRequest: POST 'route'>
resolver
<URLResolver 'diaas.urls' (None:None) '^/'>
resolver_match
ResolverMatch(func=accounts.views.login, args=(), kwargs={}, url_name=None, app_names=[], namespaces=[])
response
None
self
<django.core.handlers.wsgi.WSGIHandler object at 0x7fe2ca54a9b0>
wrapped_callback
<function WrappedAPIView at 0x7fe2ca7eee18>
lib/python3.5/site-packages/django/core/handlers/base.py in _get_response
response = middleware_method(request, callback, callback_args, callback_kwargs)
if response:
break
if response is None:
wrapped_callback = self.make_view_atomic(callback)
try:
response = wrapped_callback(request, *callback_args, **callback_kwargs) ...
except Exception as e:
response = self.process_exception_by_middleware(e, request)
# Complain if the view returned None (a common error).
if response is None:
if isinstance(callback, types.FunctionType): # FBV
▶ Local vars
Variable Value
callback
<function WrappedAPIView at 0x7fe2ca7eee18>
callback_args
()
callback_kwargs
{}
middleware_method
<bound method DebugToolbarMiddleware.process_view of <debug_toolbar.middleware.DebugToolbarMiddleware object at 0x7fe2ca555048>>
request
<WSGIRequest: POST 'route'>
resolver
<URLResolver 'diaas.urls' (None:None) '^/'>
resolver_match
ResolverMatch(func=accounts.views.login, args=(), kwargs={}, url_name=None, app_names=[], namespaces=[])
response
None
self
<django.core.handlers.wsgi.WSGIHandler object at 0x7fe2ca54a9b0>
wrapped_callback
<function WrappedAPIView at 0x7fe2ca7eee18>
lib/python3.5/site-packages/django/views/decorators/csrf.py in wrapped_view
def csrf_exempt(view_func):
"""Mark a view function as being exempt from the CSRF view protection."""
# view_func.csrf_exempt = True would also work, but decorators are nicer
# if they don't have side effects, so return a new function.
def wrapped_view(*args, **kwargs):
return view_func(*args, **kwargs) ...
wrapped_view.csrf_exempt = True
return wraps(view_func)(wrapped_view)
▶ Local vars
Variable Value
args
(<WSGIRequest: POST 'route'>,)
kwargs
{}
view_func
<function WrappedAPIView at 0x7fe2ca7eeea0>
lib/python3.5/site-packages/django/views/generic/base.py in view
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs) ...
view.view_class = cls
view.view_initkwargs = initkwargs
# take name and docstring from class
update_wrapper(view, cls, updated=())
▶ Local vars
Variable Value
args
()
cls
<class 'accounts.views.WrappedAPIView'>
initkwargs
{}
kwargs
{}
request
<WSGIRequest: POST 'route'>
self
<accounts.views.WrappedAPIView object at 0x7fe2c9a4a4e0>
lib/python3.5/site-packages/rest_framework/views.py in dispatch
def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
request = self.initialize_request(request, *args, **kwargs) ...
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
self.initial(request, *args, **kwargs)
▶ Local vars
Variable Value
args
()
kwargs
{}
request
<WSGIRequest: POST 'route'>
self
<accounts.views.WrappedAPIView object at 0x7fe2c9a4a4e0>
lib/python3.5/site-packages/rest_framework/views.py in initialize_request
Returns the initial request object.
"""
parser_context = self.get_parser_context(request)
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(), ...
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
def initial(self, request, *args, **kwargs):
"""
▶ Local vars
Variable Value
args
()
kwargs
{}
parser_context
{'args': (),
'kwargs': {},
'view': <accounts.views.WrappedAPIView object at 0x7fe2c9a4a4e0>}
request
<WSGIRequest: POST 'route'>
self
<accounts.views.WrappedAPIView object at 0x7fe2c9a4a4e0>
lib/python3.5/site-packages/rest_framework/views.py in get_authenticators
"""
return [parser() for parser in self.parser_classes]
def get_authenticators(self):
"""
Instantiates and returns the list of authenticators that this view can use.
"""
return [auth() for auth in self.authentication_classes] ...
def get_permissions(self):
"""
Instantiates and returns the list of permissions that this view requires.
"""
return [permission() for permission in self.permission_classes]
▶ Local vars
Variable Value
self
<accounts.views.WrappedAPIView object at 0x7fe2c9a4a4e0>
Metadata
Metadata
Assignees
Labels
No labels