My code is having two mixins, BasicAuthMixin and JWTAuthMixin as mentioned below. Just assume that self.authenticate method returns True and doesn't raise any exception:
from django.http import JsonResponse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import View
class BasicAuthMixin(View):
"""
Add this mixin to the views where Basic Auth is required.
"""
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
try:
self.authenticate(request)
except:
return JsonResponse({'status': 403, 'message': 'Forbidden'}, status=403, content_type='application/json')
return super(BasicAuthMixin, self).dispatch(request, *args, **kwargs)
class JWTAuthMixin(View):
"""
Add this mixin to the views where JWT based authentication is required.
"""
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
try:
self.authenticate(request)
except:
return JsonResponse({'status': 403, 'message': 'Forbidden'}, status=403, content_type='application/json')
return super(JWTAuthMixin, self).dispatch(request, *args, **kwargs)
These mixins are being used in the views based upon the authentication needed.
The actual problem begins from here: I'm trying to create another mixin AllAuthMixin which when included in any view will automatically determine which mixins need to be called based upon the Authentication Header provided:
class AllAuthMixin(View):
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
auth = request.META.get('HTTP_AUTHORIZATION') or ''
if auth.startswith('Bearer'):
return JWTAuthMixin.as_view()(request, *args, **kwargs)
elif auth.startswith('Basic'):
return BasicAuthMixin.as_view()(request, *args, **kwargs)
raise Exception('Unauthorized Access to Saurav APIs', 403)
Once I include AllAuthMixin in any of the view say /test it actually calls the appropriate Mixins but returns Method Not Allowed (GET): /test
I debugged and found that Method Not Allowed error message is coming from below line if I use basic auth:
return super(BasicAuthMixin, self).dispatch(request, *args, **kwargs)
Following illustrates a very simple example to call my view with basic auth:
>>> import requests
>>> requests.get('http://127.0.0.1:8000/test', auth=('UserName', 'Password'))
<Response [405]>
I'm not sure what I'm doing wrong here. Can anyone please help me figure it out the issue or any alternate way to achieve this. What I want is to re-use already declared mixins: BasicAuthMixn and JWTAuthMixin.