Search code examples
pythondjangodjango-rest-frameworkhttp-errordjango-middleware

DRF exception 'NotAuthenticated' raising 500 Internal Server Error in place of 401/403


I have a Django middleware where I verify a firebase IDToken.

from rest_framework import exceptions

def process_request(request):
    ...
    try:
        decoded_token = auth.verify_id_token(id_token)
        uid = decoded_token['uid']
    except:
        raise exceptions.NotAuthenticated(detail='not authenticated')

When the verification fails, auth raises an exception, which is caught by the try except block. But instead of raising 401/403 error, 500 Internal Server Error is raised by NotAuthenticated.

Is it because of some working of DRF Exceptions that this is happening ?


Solution

  • DRF handles sending status code 401 or 403 depending on the exception that got raised (NotAuthenticated, PermissionDenied) from your view.

    But since you are working with a middleware, DRF is already out of the picture. Any exceptions that you raise which are not caught or handled by default will be considered as a server error, hence giving you a 500.

    If you want your middleware to return a 401 or 403, you can use django's HttpResponse or HttpResponseForbidden like so:

    from django.http.response import HttpResponse, HttpResponseForbidden
    
    class MyMiddlware:
        def process_request(request):
            try:
                decoded_token = auth.verify_id_token(id_token)
                uid = decoded_token['uid']
            except Exception:
                return HttpResponseForbidden('not authenticated')
           # or return HttpResponse('not authenticated', status=401)