I have applied JWT authentication with HttpOnly cookies using a custom middleware. Now, the middleware checks for the presence of access and refresh tokens as HttpOnly cookies in every request. Everything works well.
But, it retuns 'KeyError': 'access' if I request for a page that does not require authentication, say, the homepage or bloglist or blogdetail page. How do I remove this need for access token in these views with permissions set to AllowAny and also in some views where only the GET method permission is set to AllowAny?
My view:
class TagView(viewsets.ModelViewSet):
queryset = Tag.objects.all()
serializer_class = TagSerializer
def get_permissions(self):
if self.request.method == 'PUT':
self.permission_classes = [permissions.IsAuthenticated,]
elif self.request.method == 'GET':
self.permission_classes = [permissions.AllowAny,]
elif self.request.method == 'POST':
self.permission_classes = [permissions.IsAuthenticated,]
return super(TagView, self).get_permissions()
If request method is GET, the middleware should pass the request even if no access cookie is found.
Now, it checks for the access cookie in every request. I added a line to skip asking for tokens if the request method is GET and if there is no cookie in the request, to mark it as AllowAny view, but I think it is unsafe.
My middleware:
class AuthorizationHeaderMiddleware:
def __init__(self, get_response=None):
self.get_response = get_response
def process_view(self, request, view_func, view_args, view_kwargs):
pass
def __call__(self, request):
if request.path == '/api/auth/login/':
return self.get_response(request)
# for AllowAny views, I am doing this, but I think it is unsafe
elif request.method == 'GET' and request.COOKIES == {}: # no cookies present
return self.get_response(request)
else:
try:
access_token = request.COOKIES['access']
key = settings.SECRET_KEY
jwt.decode(access_token, key, algorithms=["HS256"])
request.META['HTTP_AUTHORIZATION'] = f'Bearer {access_token}'
return self.get_response(request)
except jwt.ExpiredSignatureError:
refresh_cookie = request.COOKIES['refresh']
data = {"refresh": refresh_cookie}
resp = requests.post('http://127.0.0.1:8000/api/auth/refresh/', data=data)
access_token_string = json.loads(resp.text)["access"]
request.META['HTTP_AUTHORIZATION'] = f'Bearer {access_token_string}'
return self.get_response(request)
How do I allow selected AllowAny views and methods if they don't have HttpOnly JWT token cookies?