Search code examples
pythondjangodjango-rest-framework

Django and Middleware which uses request.user is always Anonymous


I'm trying to make middleware which alters some fields for the user based on subdomain, etc...

The only problem is the request.user always comes in as AnonymousUser within the middleware, but is then the correct user within the views. I've left the default authentication and session middleware django uses within the settings.

There is a similar question here: Django, request.user is always Anonymous User But doesn't overly answer the total question because I'm not using different authentication methods, and djangos authentication is running before I invoke my own middleware.

Is there a way, while using DRF, to get the request.user within the middleware? I'll show some sample code here:

class SampleMiddleware(object):

  def process_view(self, request, view_func, view_args, view_kwargs):
    #This will be AnonymousUser.  I need it to be the actual user making the request.
    print (request.user)    

  def process_response(self, request, response):
    return response

with process_request:

class SampleMiddleware(object):

  def process_request(self, request):
    #This will be AnonymousUser.  I need it to be the actual user making the request.
    print (request.user)    

  def process_response(self, request, response):
    return response

Solution

  • I've solved this problem by getting DRF token from the requests and loading request.user to the user associated to that model.

    I had the default django authentication and session middleware, but it seems DRF was using it's token auth after middleware to resolve the user (All requests were CORS requests, this might have been why). Here's my updated middleware class:

    from re import sub
    from rest_framework.authtoken.models import Token
    from core.models import OrganizationRole, Organization, User
    
    class OrganizationMiddleware(object):
    
      def process_view(self, request, view_func, view_args, view_kwargs):
        header_token = request.META.get('HTTP_AUTHORIZATION', None)
        if header_token is not None:
          try:
           token = sub('Token ', '', header_token)
            token_obj = Token.objects.get(key = token)
            request.user = token_obj.user
          except Token.DoesNotExist:
            pass
        #This is now the correct user
        print (request.user)
    

    This can be used on process_view or process_request as well.

    Hopefully this can help someone out in the future.