Django 1.10:登录需要中间件重定向循环

Django 1.10: login required middleware redirect loop

我正在编写一些中间件来有效地在所有页面上制作 @login_required。不幸的是,我在重定向循环中得到的结果。

该实现使用带有 1.10 的 "old" 样式中间件,通过 MiddlewareMixinprocess_request() 挂钩,试图在用户未通过身份验证时重定向到登录页面。

首先,我使用默认的身份验证 urls django.contrib.auth.urlsdocs 说:

This will include the following URL patterns: ^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
]

然后是中间件(是的,它已添加到 settings.py 中的 MIDDLEWARE):

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/')

登录 page/functionality 在不包含 my 中间件时工作正常,而包含它会导致每个 url 导致 ERR_TOO_MANY_REDIRECTS

我错过了什么?谢谢。

呸!我需要检查 process_request 中的 /login/ 并忽略它。

这是已实施内容的简化版本。真实版本使用 settings.py 和正则表达式来定义登录豁免 url。这种方法要归功于 Ryan Witt post

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/")