所有应用程序上的 Django 1.10 身份验证

Django 1.10 authentication on all apps

我的 Django 项目是一个具有以下目录结构的网站:

project
-- main_folder
   -- settings.py
   -- views.py
   -- urls.py [1]
   -- ...
-- app_folder
   -- views.py
   -- urls.py [2]
   -- ...
-- not_app_folder
   -- views.py
   -- urls.py [3]
   -- ...
-- manage.py

我在 urls.py [1] 中使用此代码来验证用户:

from django.contrib.auth import views as auth_views
...
urlpatterns = [
    url(r'^login/$', auth_views.login),
    ...
]

我有一个代码可以在我的所有网站页面上成功运行 Django 1.9(所有页面上的模板方法 {% if user.is_authenticated %} returns true)。

升级后身份验证在 urls.py [1] 文件的所有 url 上运行良好,但是当我移动到 urls.py [2](它是一个应用程序目录)或 urls.py [3](它是一个简单的目录),模板方法 {% if user.is_authenticated %} returns false (我所有页面都有相同的模板)。

Django 1.10 中发生了什么变化以及如何在网站的任何页面上保持身份验证有效?

我使用我在 https://djangosnippets.org/snippets/2845/ 找到的这个中间件。 它甚至在 URL 上有正则表达式白名单 (LOGIN_EXEMPT_URLS)

# -*- coding: UTF-8 -*-

# django dependencies
from django.contrib.auth.views import redirect_to_login
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.conf import settings

# python dependencies
from re import compile

#---#

EXEMPT_URLS = [compile(settings.LOGIN_URL.lstrip('/'))]
if hasattr(settings, 'LOGIN_EXEMPT_URLS'):
    EXEMPT_URLS += [compile(expr) for expr in settings.LOGIN_EXEMPT_URLS]

#---#

class LoginRequiredMiddleware:
    """
    Middleware that requires a user to be authenticated to view any page other
    than LOGIN_URL. Exemptions to this requirement can optionally be specified
    in settings via a list of regular expressions in LOGIN_EXEMPT_URLS (which
    you can copy from your urls.py).

    Requires authentication middleware and template context processors to be
    loaded. You'll get an error if they aren't.
    """
    def process_request(self, request):
        assert hasattr(request, 'user'), ("The Login Required middleware "
            "requires authentication middleware to be installed. Edit "    
            "your MIDDLEWARE_CLASSES setting to insert "
            "'django.contrib.auth.middlware.AuthenticationMiddleware'. "  
            "If that doesn't work, ensure your "
            "TEMPLATE_CONTEXT_PROCESSORS setting includes "
            "'django.core.context_processors.auth'.")
        if not request.user.is_authenticated():
            path = request.path_info.lstrip('/')
            if not any(m.match(path) for m in EXEMPT_URLS):            
                path = request.get_full_path()
                return redirect_to_login(path, settings.LOGIN_URL,
                                         REDIRECT_FIELD_NAME)

只需将它放在 django.contrib.auth.middleware.*AuthenticationMiddleware 之后到 MIDDLEWARE_CLASSES 的设置中。如果那里没有,则必须添加它。

MIDDLEWARE_CLASSES = (
    'django.middleware.security.SecurityMiddleware',
    ...
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'sis_tools.middleware.LoginRequiredMiddleware', # <-- HERE
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',
)

白名单的工作方式与 urls.py 类似,因此您可以像这样使用它:

LOGIN_EXEMPT_URLS = ( r'^about.html$', r'^legal/',)

这允许用户访问页面 sample.com/about.html 和部分 sample.com/legal/*

中的所有内容

您还必须在您的设置中设置 LOGIN_URL 到您的登录页面,如下所示:

LOGIN_PAGE = "/accounts/login"

此外,如果用户在登录页面上输入站点,设置 LOGIN_REDIRECT_URL url 跳转的位置也很方便。

LOGIN_REDIRECT_URL = "/"

升级Django时要格外小心。许多功能已被弃用,但仍在工作,但未达到预期。

此代码在 Django 1.9 中运行良好:

vars = RequestContext(request, {'key': 'value'})
return render_to_response('template.html', vars)

但是 render_to_response 很快就会被弃用,对于 Django 1.10 你应该这样写:

return render(request, 'template.html', {'key': 'value'})

您拥有多少应用程序或 views.py 文件没有区别。用户身份验证现在可以正常工作。