Установить все страницы для входа в систему, глобально? - PullRequest
33 голосов
/ 04 декабря 2011

Я хочу перенаправить доступ неаутентифицированных пользователей на страницу входа, после чего вошедший в систему пользователь должен быть перенаправлен на первоначально запрошенную страницу.

Согласно документации, это легко сделать с помощью @user_passes_test декоратор.Но, похоже, мне нужно украсить каждое представление, которое безумно, их слишком много и оно подвержено ошибкам.

Какой хороший способ включить эту функцию в глобальном масштабе (за исключением небольшого фиксированного наборапросмотров, например login)?То есть, по умолчанию все для входа в систему только + явно обрабатывать анонимный просмотр, где это необходимо.

Ответы [ 3 ]

3 голосов
/ 04 декабря 2011

посмотрите на промежуточное ПО .это функции, выполняемые в различных точках цикла запроса, например, перед вызовом каждого представления.

, поскольку вы, возможно, захотите исключить из этого определенные представления, я, например, посмотрю, как работает промежуточное программное обеспечение csrf вместе с декоратором csrf_exempt.

см. [SOURCE]/django/views/decorators/csrf.py и [SOURCE]/django/middleware/csrf.py

3 голосов
/ 04 декабря 2011

Способ, которым я решил это, состоял в том, чтобы иметь класс mixin, с декоратором (или любым другим кодом, который вам нужен).Хотя вы должны помнить, что нужно вызывать функцию super(Class, self).get(...), поэтому я думаю, что она, в конце концов, не так уж и отличается.

С другой стороны, наличие набора миксинов, которые делают разные вещи, которые, как я обнаружил, было довольно хорошоочень простое представление, чтобы сделать много без большого количества кода.

Редактировать

Вот как я делал в своем последнем проекте:

class BaseAuthMixin(object):
    def auth_check(self, user):
        return True

    def dispatch(self, request, *args, **kwargs):
        if not self.auth_check(request.user):
            from django.http import HttpResponseRedirect
            from django.contrib.auth import logout

            is_web = False
            is_live = False

            if hasattr(self, 'get_url_name'):
                from django.core.urlresolvers import reverse
                from django.core.urlresolvers import NoReverseMatch

                try:
                    next = reverse(self.get_url_name(), kwargs=kwargs)
                except NoReverseMatch:
                    next = ''
                else:
                    next= '?next=' + next

            logout(request)

            redirect_url = settings.LOGIN_URL
            redirect_url += next

            return HttpResponseRedirect(redirect_url)
        else:
            return super(BaseAuthMixin, self).dispatch(request, *args, **kwargs)

class LoginRequiredMixin(BaseAuthMixin):
    """
    Check if the view needs the user to be logged in.
    """
    def auth_check(self, user):
        if not super(LoginRequiredMixin, self).auth_check(user):
            return False
        else:
            if hasattr(self, 'login_required'):
                if self.login_required and not user.is_authenticated():
                    return False
        return True

class MyDefaultMixin(LoginRequiredMixin):
    """
    Mixin that inherits from all common view mixins.
    """
    pass

Затем вышеприведенное используетсяклассы представлений (я использовал Django 1.3 с представлениями на основе классов):

from django.views.generic import TemplateView

class SomeViewClass(TemplateView, MyDefaultMixin):
    # Used by 'LoginRequiredMixin' to check if a user has to be logged in
    login_required = True

    # Template for the Django TemplateView
    template_name = "some_view_template.html"

Требуется представление для обработки имени входа (с URL-адресом в settings.LOGIN_URL), содержащее форму со скрытым полем под названиемnext.Это поле должно быть задано контекстной переменной для перехода на страницу после успешного входа в систему.

Если все представления наследуются от базового миксина (MyDefaultMixin в моем коде выше), он автоматически проверит, чтоПользователь вошел в систему iv. Представление содержит атрибут с именем login_required, для которого установлено значение True.

Возможно, есть лучшие способы сделать это, но это то, что я сделал, и это сработало очень хорошо.

1 голос
/ 28 февраля 2018
from django.shortcuts import redirect
from django.conf import settings


class LoginRequiredMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        self.login_url = settings.LOGIN_URL
        self.open_urls = [self.login_url] + \
                         getattr(settings, 'OPEN_URLS', [])

    def __call__(self, request):
        if not request.user.is_authenticated \
        and not request.path_info in self.open_urls:
            return redirect(self.login_url+'?next='+request.path)

        return self.get_response(request)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...