pythondjangoimpersonation

Django user impersonation by admin


I have a Django app. When logged in as an admin user, I want to be able to pass a secret parameter in the URL and have the whole site behave as if I were another user.

Let's say I have the URL /my-profile/ which shows the currently logged in user's profile. I want to be able to do something like /my-profile/?__user_id=123 and have the underlying view believe that I am actually the user with ID 123 (thus render that user's profile).

Why do I want that?

Simply because it's much easier to reproduce certain bugs that only appear in a single user's account.

My questions:

  1. What would be the easiest way to implement something like this?

  2. Is there any security concern I should have in mind when doing this? Note that I (obviously) only want to have this feature for admin users, and our admin users have full access to the source code, database, etc. anyway, so it's not really a "backdoor"; it just makes it easier to access a user's account.


Solution

  • I solved this with a simple middleware. It also handles redirects (that is, the GET parameter is preserved during a redirect). Here it is:

    class ImpersonateMiddleware(object):
        def process_request(self, request):
            if request.user.is_superuser and "__impersonate" in request.GET:
                request.user = models.User.objects.get(id=int(request.GET["__impersonate"]))
    
        def process_response(self, request, response):
            if request.user.is_superuser and "__impersonate" in request.GET:
                if isinstance(response, http.HttpResponseRedirect):
                    location = response["Location"]
                    if "?" in location:
                        location += "&"
                    else:
                        location += "?"
                    location += "__impersonate=%s" % request.GET["__impersonate"]
                    response["Location"] = location
            return response