Django 1.10: требуется вход в цикл перенаправления промежуточного программного обеспечения

Я пишу немного промежуточного программного обеспечения, чтобы эффективно сделать @login_required на всех страницах. К сожалению, то, что у меня есть, приводит к циклу перенаправления.

Реализация использует промежуточное ПО «старого» стиля с 1.10 через MiddlewareMixin и process_request() хук в попытке перенаправить на страницу входа всякий раз, когда пользователь не аутентифицирован.

Во-первых, я использую URL-адреса аутентификации по умолчанию django.contrib.auth.urls. В документах говорится :

Это будет включать следующие шаблоны URL: ^login/$ [name='login']...

# main URLConf urls.py
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include('django.contrib.auth.urls')),  # https://docs.djangoproject.com/en/1.10/topics/auth/default/#module-django.contrib.auth.views
]

Тогда вот промежуточное ПО (да, оно добавлено в MIDDLEWARE в settings.py):

from django.http import HttpResponseRedirect
from django.utils.deprecation import MiddlewareMixin

class LoginRequiredMiddleware(MiddlewareMixin):

    def process_request(self, request):
        if not request.user.is_authenticated():
            return HttpResponseRedirect('/login/')

Страница/функции входа в систему отлично работают, когда мое промежуточное ПО не включено, в то время как его включение приводит к тому, что каждый URL-адрес вызывает ERR_TOO_MANY_REDIRECTS.

Что мне не хватает? Спасибо.


person conner.xyz    schedule 29.11.2016    source источник


Ответы (1)


Дох! Мне нужно было проверить /login/ в process_request и игнорировать его.

Вот упрощенная версия того, что реализовано. Настоящая версия использует settings.py и регулярные выражения для определения URL-адресов без входа в систему. Большое спасибо Райану Уитту в сообщении об этом подходе.

class LoginRequiredMiddleware(MiddlewareMixin):

    def process_request(self, request):
        if not request.user.is_authenticated():
            path = request.path_info.lstrip('/')
            # If path is not root url ('') and path is not exempt from authentication
            if not path or not any(path != eu for eu in ["/login", "admin"]):
                return HttpResponseRedirect("/login/")
person conner.xyz    schedule 29.11.2016
comment
@PrakharTrivedi Я понял. Через несколько минут я добавлю некоторые подробности в свой ответ. Спасибо. - person conner.xyz; 29.11.2016