2015-06-11 3 views
4

У меня есть настройки приложения 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. Если есть, что мне делать?

+3

Я думаю, вам нужно [промежуточное программное обеспечение] (https://docs.djangoproject.com/en/1.8/topics/http/middleware/#process_request). Это также может быть полезно [запрос и ответные документы из Django] (https://docs.djangoproject.com/en/1.8/topics/http/middleware/#hooks-and-application-order) – Gocht

ответ

3

Вы можете написать middleware, что позволит вам сделать некоторые работы по просьбе перед обработкой его в представлениях. В файле с именем 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', 
) 
1

Я думаю, что это невозможно определить по шаблону url, который включает в себя другие (позже будет немного подробнее об этом узнать), но, по крайней мере, это возможно в CustomAdmin.urls с помощью декоратора user_passes_test.

# 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' 
    ), 
) 
0

От ccbv.co.uk и от Django Class-bases views docs, dispatch() является первым методом, который называется в одном классе базе просмотра.

рабочего Просмотра класса

  1. диспетчерские()
  2. http_method_not_allowed()
  3. опции()

Имейте в виде, чем весь родовой вид наследует Посмотреть класс

Middleware - хорошее решение, но если вы это сделаете не нужно предварительно обрабатывать каждый запрос, вы можете использовать доступ к смесителю.

Как я уже говорил, 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... 

Я надеюсь, вы найдете это полезным.

Смежные вопросы