首页 > 解决方案 > Is there any way to edit the request user in django middleware?

问题描述

I am creating a way for Superusers to assume control of another user's account, but allow logging to show that all actions performed in this time are done by the superuser.

The idea I have currently is to process the request in middleware and look for a specific header. If that header exists I will replace the current request.user with the user specified in the header. Currently the middleware looks like this:

class ControlledUserMiddleware(MiddlewareMixin):

def process_request(self, request):
    controlled_user = request.META.get('HTTP_CONTROLLED_USER', None)
    if controlled_user:
        request.user = User.objects.get(uuid=controlled_user)

I have found that - despite the fact I have placed this after the auth middleware in my settings file - the user in the request is always 'anonymous user' when it reaches this function.

This method is not working currently and I was wondering if it was possible at all to edit the request.user before it reaches view logic.

Edit as requested in comments, here are the REST_FRAMEWORK settings:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated'
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.MultiPartParser',
        'rest_framework.parsers.FormParser',
    ]
}

标签: djangopython-3.xdjango-rest-frameworkdjango-middleware

解决方案


找到了,是的,有可能。事实证明,正如 mehamasum 在上面的评论中正确指出的那样,TokenAuthenticationDEFAULT_AUTHENTICATION_CLASSES的请求中的令牌覆盖了 request.user 。这可以通过添加_force_auth_userforce_auth_token到中间件函数来覆盖,如下所示:

class ControlledUserMiddleware(MiddlewareMixin):

def process_request(self, request):
    controlled_user_uuid = request.META.get('HTTP_CONTROLLED_USER', None)
    if controlled_user_uuid:
        controlled_user = User.objects.get(uuid=controlled_user_uuid)
        request._force_auth_user = controlled_user
        request._force_auth_token = Token.objects.get(user=controlled_user)

推荐阅读