Django用户模拟管理员

ibz*_*ibz 20 python django impersonation

我有一个Django应用程序.以管理员用户身份登录时,我希望能够在URL中传递一个秘密参数,并使整个站点的行为就像我是另一个用户一样.

假设我有一个/my-profile/显示当前登录用户个人资料的URL .我希望能够做类似的事情/my-profile/?__user_id=123并让底层视图相信我实际上是ID为123的用户(从而呈现用户的个人资料).

我为什么要这样?

仅仅因为重现某些只出现在单个用户帐户中的错误要容易得多.

我的问题:

  1. 实现这样的最简单的方法是什么?

  2. 这样做时我是否应该考虑安全问题?请注意,我(显然)只想为管理员用户提供此功能,而且我们的管理员用户无论如何都可以完全访问源代码,数据库等,所以它不是真正的"后门"; 它只是让访问用户的帐户更容易.

Cha*_*her 33

我没有足够的声誉来编辑或回复(我认为),但我发现尽管ionaut的解决方案在简单的情况下工作,但对我来说更强大的解决方案是使用会话变量.这样,即使是AJAX请求也可以正确提供,而无需修改请求URL以包含GET模拟参数.

class ImpersonateMiddleware(object):
    def process_request(self, request):
        if request.user.is_superuser and "__impersonate" in request.GET:
            request.session['impersonate_id'] = int(request.GET["__impersonate"])
        elif "__unimpersonate" in request.GET:
            del request.session['impersonate_id']
        if request.user.is_superuser and 'impersonate_id' in request.session:
            request.user = User.objects.get(id=request.session['impersonate_id'])
Run Code Online (Sandbox Code Playgroud)

用法:

log in: http://localhost/?__impersonate=[USERID]
log out (back to admin): http://localhost/?__unimpersonate=True
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这非常有用!我只是改变它来操作用户名而不是ids,因为这对我们更有意义. (2认同)

Ham*_*ner 10

看起来很多其他人都有这个问题,并且已经编写了可重复使用的应用程序来执行此操作,并且至少有一些列在django软件包页面上以供用户切换.写作时最活跃的似乎是:

  • django-hijack在管理员的用户列表中放置一个"劫持"按钮,并在您劫持帐户时在页面顶部添加一些内容.
  • impostor意味着您可以使用用户名"me as other"和您自己的密码登录
  • django-impersonate设置URL以开始冒充用户,停止,搜索等

  • django-hijack结识了我的一天.感谢@hamish推荐这些套餐. (3认同)

ibz*_*ibz 9

我用一个简单的中间件解决了这个问题.它还处理重定向(即,在重定向期间保留GET参数).这里是:

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
Run Code Online (Sandbox Code Playgroud)

  • 他没有理由对这个特征如此偏执.管理员可以删除用户.管理员可以编辑用户.管理员可以杀死该网站.以他们身份登录也同样安全.只要superadmin登录是安全的,那么"Su"功能也是如此.如果存在对管理员的担忧,则可以记录会话被su'd的事实,使得事件是可追踪的. (5认同)
  • 我使用类似的中间件,而是使用自定义标头.X-Masquerade-As:<用户名>.然后,它会在请求中设置用户属性,但也会将超级用户设置为"real_user",然后将其用于日志记录. (2认同)