I currently have a Django setup that followed the guide below. Pretty much, it's a workaround that allows for HTTPOnly cookies to be used with Django Rest Framework JWT authentication. It worked fine in Django 3.2, but I'm attempting to upgrade to Django 4, and I'm now running into the error below
How to store JWT tokens in HttpOnly cookies with DRF djangorestframework-simplejwt package?
Error:
__init__() missing 1 required positional argument: 'get_response'
I'm still a bit new to Django and DRF, so I have no idea what could be going on.
Edit:
Apologies, forgot to add some details. The error is in the following code, on CSRFCheck():
from rest_framework_simplejwt.authentication import JWTAuthentication
from django.conf import settings
from rest_framework.authentication import CSRFCheck
from rest_framework import exceptions
def enforce_csrf(request):
# Enforce CSRF validation.
check = CSRFCheck()
check.process_request(request)
# populates request.META['CSRF_COOKIE'], which is used in process_view()
reason = check.process_view(request, None, (), {})
if reason:
# CSRF failed, bail with explicit error message
raise exceptions.PermissionDenied('CSRF Failed: %s' % reason)
class CustomAuthentication(JWTAuthentication):
def authenticate(self, request):
header = self.get_header(request)
if header is None:
raw_token = request.COOKIES.get(settings.SIMPLE_JWT['AUTH_COOKIE']) or None
else:
raw_token = self.get_raw_token(header)
if raw_token is None:
return None
validated_token = self.get_validated_token(raw_token)
enforce_csrf(request)
return self.get_user(validated_token), validated_token
Traceback messages: (Full error: jsfiddle.net/Luizram/t7u03cqy/1 )
/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py, line 55, in inner
return inner
else:
@wraps(get_response)
def inner(request):
try:
response = get_response(request) <- Line 55
…
except Exception as exc:
response = response_for_exception(request, exc)
return response
return inner
Local vars /usr/local/lib/python3.8/site-packages/django/core/handlers/base.py, line 197, in _get_response
if response is None:
wrapped_callback = self.make_view_atomic(callback)
# If it is an asynchronous view, run it in a subthread.
if asyncio.iscoroutinefunction(wrapped_callback):
wrapped_callback = async_to_sync(wrapped_callback)
try:
response = wrapped_callback(request, *callback_args, **callback_kwargs) <- Line 197
…
except Exception as e:
response = self.process_exception_by_middleware(e, request)
if response is None:
raise
# Complain if the view returned None (a common error).
Local vars /usr/local/lib/python3.8/site-packages/django/views/decorators/csrf.py, line 54, 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) <- Line 54
…
wrapped_view.csrf_exempt = True
return wraps(view_func)(wrapped_view)
Local vars /usr/local/lib/python3.8/site-packages/django/views/generic/base.py, line 84, in view
self = cls(**initkwargs)
self.setup(request, *args, **kwargs)
if not hasattr(self, "request"):
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
return self.dispatch(request, *args, **kwargs) <- Line 84
…
view.view_class = cls
view.view_initkwargs = initkwargs
# __name__ and __qualname__ are intentionally left unchanged as
# view_class should be used to robustly determine the name of the view
Local vars /usr/local/lib/python3.8/site-packages/rest_framework/views.py, line 509, in dispatch
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc) <- Line 509
…
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
def options(self, request, *args, **kwargs):
"""
Local vars /usr/local/lib/python3.8/site-packages/rest_framework/views.py, line 469, in handle_exception
exception_handler = self.get_exception_handler()
context = self.get_exception_handler_context()
response = exception_handler(exc, context)
if response is None:
self.raise_uncaught_exception(exc) <- Line 469
…
response.exception = True
return response
def raise_uncaught_exception(self, exc):
if settings.DEBUG:
Local vars /usr/local/lib/python3.8/site-packages/rest_framework/views.py, line 480, in raise_uncaught_exception
def raise_uncaught_exception(self, exc):
if settings.DEBUG:
request = self.request
renderer_format = getattr(request.accepted_renderer, 'format')
use_plaintext_traceback = renderer_format not in ('html', 'api', 'admin')
request.force_plaintext_errors(use_plaintext_traceback)
raise exc <- Line 480
…
# Note: Views are made CSRF exempt from within `as_view` as to prevent
# accidental removal of this exemption in cases where `dispatch` needs to
# be overridden.
def dispatch(self, request, *args, **kwargs):
"""
Local vars /usr/local/lib/python3.8/site-packages/rest_framework/views.py, line 497, in dispatch
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) <- Line 497
…
# Get the appropriate handler method
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
Local vars /usr/local/lib/python3.8/site-packages/rest_framework/views.py, line 414, in initial
request.accepted_renderer, request.accepted_media_type = neg
# Determine the API version, if versioning is in use.
version, scheme = self.determine_version(request, *args, **kwargs)
request.version, request.versioning_scheme = version, scheme
# Ensure that the incoming request is permitted
self.perform_authentication(request) <- Line 414
…
self.check_permissions(request)
self.check_throttles(request)
def finalize_response(self, request, response, *args, **kwargs):
"""
Returns the final response object.
Local vars /usr/local/lib/python3.8/site-packages/rest_framework/views.py, line 324, in perform_authentication
"""
Perform authentication on the incoming request.
Note that if you override this and simply 'pass', then authentication
will instead be performed lazily, the first time either
`request.user` or `request.auth` is accessed.
"""
request.user <- Line 324
…
def check_permissions(self, request):
"""
Check if the request should be permitted.
Raises an appropriate exception if the request is not permitted.
"""
Local vars /usr/local/lib/python3.8/site-packages/rest_framework/request.py, line 227, in user
def user(self):
"""
Returns the user associated with the current request, as authenticated
by the authentication classes provided to the request.
"""
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate() <- Line 227
…
return self._user
@user.setter
def user(self, value):
"""
Sets the user on the current request. This is necessary to maintain
Local vars /usr/local/lib/python3.8/site-packages/rest_framework/request.py, line 380, in _authenticate
def _authenticate(self):
"""
Attempt to authenticate the request using each authentication instance
in turn.
"""
for authenticator in self.authenticators:
try:
user_auth_tuple = authenticator.authenticate(self) <- Line 380
…
except exceptions.APIException:
self._not_authenticated()
raise
if user_auth_tuple is not None:
self._authenticator = authenticator
Local vars /django/users/authenticate.py, line 30, in authenticate
if header is None:
raw_token = request.COOKIES.get(settings.SIMPLE_JWT['AUTH_COOKIE']) or None
else:
raw_token = self.get_raw_token(header)
if raw_token is None:
return None
validated_token = self.get_validated_token(raw_token)
enforce_csrf(request) <- Line 30
…
return self.get_user(validated_token), validated_token
Local vars /django/users/authenticate.py, line 10, in enforce_csrf
from rest_framework.authentication import CSRFCheck
from rest_framework import exceptions
def enforce_csrf(request):
# Enforce CSRF validation.
check = CSRFCheck() <- Line 10
…
check.process_request(request)
# populates request.META['CSRF_COOKIE'], which is used in process_view()
reason = check.process_view(request, None, (), {})
if reason:
# CSRF failed, bail with explicit error message