繁体   English   中英

检查django中每个请求的授权

[英]Check authorization for each request in django

我有一个Django应用程序设置如下:

MyApp
    CustomAdmin
        urls
        models
        views
    MainApp
        settings
        urls
        wsgi
    SomeOtherApp
        admin
        models
        views

现在,在我的MainApp.urls ,我设置了以下网址:

url(r'^api/admin/', include('CustomAdmin.urls')),

CustomAdmin ,我希望有一种机制来检查请求是否由superuser进行,而不管相关视图。 如果它是由超级用户创建的,则该请求应由关联的视图函数处理,否则它应该抛出403或类似的错误。

我在Laravel中使用了类似的东西,如下所示

Route::group(
    array(
        'before' => 'auth.admin',
        'prefix' => 'api/admin'        
        ),
    function(){
        ....
    });

我不确定Django中是否存在这样的机制。 如果有,我该怎么办?

您可以编写一个中间件 ,允许您在视图中处理请求之前对请求执行一些操作。 在名为middleware.py的文件中,放入:

from django.contrib.auth.views import redirect_to_login

class AllowSuperUserOnly(object):
    def process_request(self, request):
        if request.path.startswith('/api/admin/'):
            if not request.user.is_superuser:
                return redirect_to_login(request.path)
        # Continue processing the request as usual:
        return None

并将中间件添加到settings.py 它看起来应该类似于:

MIDDLEWARE_CLASSES = (
    ...
    'your_app.middleware.AllowSuperUserOnly',
)

我认为不可能在包含其他的url模式上定义它(稍后会对此进行更多测试),但至少可以通过使用user_passes_test装饰器在CustomAdmin.urls进行测试。

# CustomAdmin/urls.py
from django.contrib.auth.decorators import user_passes_test
from CustomAdmin import views

requires_superuser = user_passes_test(lambda x: x.is_superuser)

urlpatterns = patterns(
    '',
    url(  # with a class based view
        r'^$', 
        requires_superuser(views.SomeView.as_view()), 
        name='someview'
    ),
    url(  # with a functional view
        r'^(?P<foo>\w+)/$', 
        requires_superuser(views.someotherview),    
        name='someotherview'
    ),
)

ccbv.co.ukDjango Class-bases视图文档中dispatch()是在基于类的视图中调用的第一个方法。

查看课程工作流程

  1. 调度()
  2. http_method_not_allowed()
  3. 选项()

请记住,所有通用视图都继承View类

中间件是一个很好的解决方案,但如果您不需要预处理每个请求,您可以使用访问混合

正如我之前所说, dispatch()是第一个执行的方法,因此您可以重新编写它以授予或拒绝访问视图。

这是dispatch默认代码:

def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    if request.method.lower() in self.http_method_names:
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)

你可以写一个mixin类:

class SuperuserRequiredMixin(object):
    """
    Mixin allows you to require a user with `is_superuser` set to True.
    """

    login_url = settings.LOGIN_URL  # LOGIN_URL from project settings
    raise_exception = False  # Default whether to raise an exception to none
    redirect_field_name = REDIRECT_FIELD_NAME  # Set by django.contrib.auth

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_superuser:  # If the user is a standard user,
            if self.raise_exception:  # *and* if an exception was desired
                return HttpResponseForbidden()  # return a forbidden response.
            else:
                # otherwise, redirect the user to the login page.
                # Also, handily, sets the `next` GET argument for
                # future redirects.
                path = urlquote(request.get_full_path())
                tup = self.login_url, self.redirect_field_name, path
                return HttpResponseRedirect("%s?%s=%s" % tup)

        return super(SuperuserRequiredMixin, self).dispatch(request, *args, **kwargs)

然后,您可以在视图中使用它。 我们假设一个ListView

from django.views.generic import ListView
from somewhere import SuperuserRequiredMixin

class MyView(ListView, SuperuserRequiredMixin):
    ...
    # Do what you usually do...

希望这个对你有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM