Django:如何将login_required decorator应用到整个站点(不包括静态媒体)?

时间:2022-06-02 07:22:34

The example provides a snippet for an application level view, but what if I have lots of different (and some non-application) entries in my "urls.py" file, including templates? How can I apply this login_required decorator to each of them?

这个示例为应用程序级别的视图提供了一个代码片段,但是如果我的“url”中有许多不同的(和一些非应用程序)条目,该怎么办呢?py”文件,包括模板吗?我如何将这个login_required decorator应用到它们中的每一个?

(r'^foo/(?P<slug>[-\w]+)/$', 'bugs.views.bug_detail'),
(r'^$', 'django.views.generic.simple.direct_to_template', {'template':'homepage.html'}),

8 个解决方案

#1


25  

Dropped this into a middleware.py file in my project root (taken from http://onecreativeblog.com/post/59051248/django-login-required-middleware)

将其放到中间件中。项目根目录中的py文件(取自http://onecreativeblog.com/post/59051248/django-login-required-middleware)

from django.http import HttpResponseRedirect
from django.conf import settings
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):
                return HttpResponseRedirect(settings.LOGIN_URL)

Then appended projectname.middleware.LoginRequiredMiddleware to my MIDDLEWARE_CLASSES in settings.py.

然后附加projectname.middleware。在settings.py中登录中间件到我的MIDDLEWARE_CLASSES。

#2


11  

For those who have come by later to this, you might find that django-stronghold fits your usecase well. You whitelist any urls you want to be public, the rest are login required.

对于那些后来来这里的人,你可能会发现django要塞很适合你的使用。您将任何您想要公开的url列表为白色,其余的都需要登录。

https://github.com/mgrouchy/django-stronghold

https://github.com/mgrouchy/django-stronghold

#3


8  

Here's a slightly shorter middleware.

这里有一个稍短的中间件。

from django.contrib.auth.decorators import login_required

class LoginRequiredMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        if not getattr(view_func, 'login_required', True):
            return None
        return login_required(view_func)(request, *view_args, **view_kwargs)

You'll have to set "login_required" to False on each view you don't need to be logged in to see:

您必须在每个视图上设置“login_required”为False,您不需要登录才能查看:

Function-views:

Function-views:

def someview(request, *args, **kwargs):
    # body of view
someview.login_required = False

Class-based views:

基于类视图:

class SomeView(View):
    login_required = False
    # body of view

#or

class SomeView(View):
    # body of view
someview = SomeView.as_view()
someview.login_required = False

This means you'll have to do something about the login-views, but I always end up writing my own auth-backend anyway.

这意味着您将不得不对登录视图做一些事情,但是我总是最终编写自己的auth-后端。

#4


2  

Use middleware.

使用中间件。

http://www.djangobook.com/en/2.0/chapter17/ and http://docs.djangoproject.com/en/1.2/topics/http/middleware/#topics-http-middleware

http://www.djangobook.com/en/2.0/chapter17/和http://docs.djangoproject.com/en/1.2/topics/http/middleware/ # topics-http-middleware

I'm assuming this didn't change a whole lot in 1.2

假设这在1。2中没有太大变化

Middleware allows you to create a class with methods who will process every request at various times/conditions, as you define.

中间件允许您创建具有方法的类,这些方法将在您定义的不同时间/条件下处理每个请求。

for example process_request(request) would fire before your view, and you can force authentication and authorization at this point.

例如,process_request(request)将在视图之前启动,您可以在此时强制进行身份验证和授权。

#5


2  

Here is the classical LoginRequiredMiddleware for Django 1.10+:

下面是Django 1.10+的典型LoginRequiredMiddleware:

from django.utils.deprecation import MiddlewareMixin

class LoginRequiredMiddleware(MiddlewareMixin):
    """
    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).
    """
    def process_request(self, request):
        assert hasattr(request, 'user'), """
        The Login Required middleware needs to be after AuthenticationMiddleware.
        Also make sure to include the template context_processor:
        'django.contrib.auth.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):
                return HttpResponseRedirect(settings.LOGIN_URL)

Noteworthy differences:

值得注意的差异:

  • path.to.LoginRequiredMiddleware should be included in MIDDLEWARE not MIDDLEWARE_CLASSES in settings.py.
  • path.to。应该在settings.py中包含LoginRequiredMiddleware,而不是MIDDLEWARE_CLASSES。
  • is_authenticated is a bool not a method.
  • is_authenticated是bool,不是方法。
  • see the docs for more info (although some parts are not very clear).
  • 查看文档了解更多信息(尽管有些部分不是很清楚)。

#6


0  

In addition to meder omuraliev answer if you want exempt url like this (with regexp):

除了meder omuraliev的回答,如果你想要像这样的豁免url(与regexp):

url(r'^my/url/(?P<pk>[0-9]+)/$', views.my_view, name='my_url')

add it to EXEMPT_URLS list like this:

将其添加到豁免权url列表如下:

LOGIN_EXEMPT_URLS = [r'^my/url/([0-9]+)/$']

r'..' in the beginning of the string necessary.

r的. .在必要的绳子的开头。

#7


0  

Django Login Required Middleware

Django登录所需的中间件

Put this code in middleware.py :

将此代码放在中间件中。py:

from django.http import HttpResponseRedirect
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin
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(MiddlewareMixin):
    def process_request(self, request):
        assert hasattr(request, 'user')
        if not request.user.is_authenticated:
            path = request.path_info.lstrip('/')
            if not any(m.match(path) for m in EXEMPT_URLS):
                return HttpResponseRedirect(settings.LOGIN_URL)

And, in settings.py :

在设置。py:

LOGIN_URL = '/app_name/login'

LOGIN_EXEMPT_URLS=(
    r'/app_name/login/',
)

MIDDLEWARE_CLASSES = (
    # ...
    'python.path.to.LoginRequiredMiddleware',
)

Like this : 'app_name.middleware.LoginRequiredMiddleware'

是这样的:“app_name.middleware.LoginRequiredMiddleware”

#8


-1  

Here's an example for new-style middleware in Django 1.10+:

下面是Django 1.10+中的一种新型中间件示例:

from django.contrib.auth.decorators import login_required
from django.urls import reverse

def login_required_middleware(get_response):
    """
        Require user to be logged in for all views. 
    """
    exceptions = {'/admin/login/'}
    def middleware(request):
        if request.path in exceptions:
            return get_response(request)
        return login_required(get_response, login_url=reverse('admin:login'))(request)
    return middleware

This example exempts the admin login form to avoid redirect loop, and uses that form as the login url.

这个示例免除管理登录表单以避免重定向循环,并使用该表单作为登录url。

#1


25  

Dropped this into a middleware.py file in my project root (taken from http://onecreativeblog.com/post/59051248/django-login-required-middleware)

将其放到中间件中。项目根目录中的py文件(取自http://onecreativeblog.com/post/59051248/django-login-required-middleware)

from django.http import HttpResponseRedirect
from django.conf import settings
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):
                return HttpResponseRedirect(settings.LOGIN_URL)

Then appended projectname.middleware.LoginRequiredMiddleware to my MIDDLEWARE_CLASSES in settings.py.

然后附加projectname.middleware。在settings.py中登录中间件到我的MIDDLEWARE_CLASSES。

#2


11  

For those who have come by later to this, you might find that django-stronghold fits your usecase well. You whitelist any urls you want to be public, the rest are login required.

对于那些后来来这里的人,你可能会发现django要塞很适合你的使用。您将任何您想要公开的url列表为白色,其余的都需要登录。

https://github.com/mgrouchy/django-stronghold

https://github.com/mgrouchy/django-stronghold

#3


8  

Here's a slightly shorter middleware.

这里有一个稍短的中间件。

from django.contrib.auth.decorators import login_required

class LoginRequiredMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        if not getattr(view_func, 'login_required', True):
            return None
        return login_required(view_func)(request, *view_args, **view_kwargs)

You'll have to set "login_required" to False on each view you don't need to be logged in to see:

您必须在每个视图上设置“login_required”为False,您不需要登录才能查看:

Function-views:

Function-views:

def someview(request, *args, **kwargs):
    # body of view
someview.login_required = False

Class-based views:

基于类视图:

class SomeView(View):
    login_required = False
    # body of view

#or

class SomeView(View):
    # body of view
someview = SomeView.as_view()
someview.login_required = False

This means you'll have to do something about the login-views, but I always end up writing my own auth-backend anyway.

这意味着您将不得不对登录视图做一些事情,但是我总是最终编写自己的auth-后端。

#4


2  

Use middleware.

使用中间件。

http://www.djangobook.com/en/2.0/chapter17/ and http://docs.djangoproject.com/en/1.2/topics/http/middleware/#topics-http-middleware

http://www.djangobook.com/en/2.0/chapter17/和http://docs.djangoproject.com/en/1.2/topics/http/middleware/ # topics-http-middleware

I'm assuming this didn't change a whole lot in 1.2

假设这在1。2中没有太大变化

Middleware allows you to create a class with methods who will process every request at various times/conditions, as you define.

中间件允许您创建具有方法的类,这些方法将在您定义的不同时间/条件下处理每个请求。

for example process_request(request) would fire before your view, and you can force authentication and authorization at this point.

例如,process_request(request)将在视图之前启动,您可以在此时强制进行身份验证和授权。

#5


2  

Here is the classical LoginRequiredMiddleware for Django 1.10+:

下面是Django 1.10+的典型LoginRequiredMiddleware:

from django.utils.deprecation import MiddlewareMixin

class LoginRequiredMiddleware(MiddlewareMixin):
    """
    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).
    """
    def process_request(self, request):
        assert hasattr(request, 'user'), """
        The Login Required middleware needs to be after AuthenticationMiddleware.
        Also make sure to include the template context_processor:
        'django.contrib.auth.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):
                return HttpResponseRedirect(settings.LOGIN_URL)

Noteworthy differences:

值得注意的差异:

  • path.to.LoginRequiredMiddleware should be included in MIDDLEWARE not MIDDLEWARE_CLASSES in settings.py.
  • path.to。应该在settings.py中包含LoginRequiredMiddleware,而不是MIDDLEWARE_CLASSES。
  • is_authenticated is a bool not a method.
  • is_authenticated是bool,不是方法。
  • see the docs for more info (although some parts are not very clear).
  • 查看文档了解更多信息(尽管有些部分不是很清楚)。

#6


0  

In addition to meder omuraliev answer if you want exempt url like this (with regexp):

除了meder omuraliev的回答,如果你想要像这样的豁免url(与regexp):

url(r'^my/url/(?P<pk>[0-9]+)/$', views.my_view, name='my_url')

add it to EXEMPT_URLS list like this:

将其添加到豁免权url列表如下:

LOGIN_EXEMPT_URLS = [r'^my/url/([0-9]+)/$']

r'..' in the beginning of the string necessary.

r的. .在必要的绳子的开头。

#7


0  

Django Login Required Middleware

Django登录所需的中间件

Put this code in middleware.py :

将此代码放在中间件中。py:

from django.http import HttpResponseRedirect
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin
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(MiddlewareMixin):
    def process_request(self, request):
        assert hasattr(request, 'user')
        if not request.user.is_authenticated:
            path = request.path_info.lstrip('/')
            if not any(m.match(path) for m in EXEMPT_URLS):
                return HttpResponseRedirect(settings.LOGIN_URL)

And, in settings.py :

在设置。py:

LOGIN_URL = '/app_name/login'

LOGIN_EXEMPT_URLS=(
    r'/app_name/login/',
)

MIDDLEWARE_CLASSES = (
    # ...
    'python.path.to.LoginRequiredMiddleware',
)

Like this : 'app_name.middleware.LoginRequiredMiddleware'

是这样的:“app_name.middleware.LoginRequiredMiddleware”

#8


-1  

Here's an example for new-style middleware in Django 1.10+:

下面是Django 1.10+中的一种新型中间件示例:

from django.contrib.auth.decorators import login_required
from django.urls import reverse

def login_required_middleware(get_response):
    """
        Require user to be logged in for all views. 
    """
    exceptions = {'/admin/login/'}
    def middleware(request):
        if request.path in exceptions:
            return get_response(request)
        return login_required(get_response, login_url=reverse('admin:login'))(request)
    return middleware

This example exempts the admin login form to avoid redirect loop, and uses that form as the login url.

这个示例免除管理登录表单以避免重定向循环,并使用该表单作为登录url。