Django,将所有未经过身份验证的用户重定向到登录页面

xpa*_*nta 13 python django

我有一个django网站,里面有很多网址和观点.现在,我已要求将所有未经过身份验证的用户重定向到某个目标网页.因此,所有视图都必须检查是否user.is_authenticated()返回到一组新的着陆页.

它可以以一种漂亮的方式完成,而不是弄乱我views.py/ urls.py那么多吗?

小智 24

有一种更简单的方法,只需将"login_url"参数添加到@login_required,如果用户没有登录,他将被重定向到登录页面.你可以在这里找到它

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
def my_view(request):
    ...
Run Code Online (Sandbox Code Playgroud)

  • @Solal 使用 `LoginRequiredMixin` 例如 `class someView(LoginRequiredMixin, CreateView):` 等。在正文中不要忘记添加 `login_url` 将页面重定向到。 (3认同)
  • 优雅的解决方案完美无瑕,就像一个魅力。已将登录和注销 url 添加到我的登录/注销 url 中,它们反过来有助于完美重定向。感谢分享。 (2认同)

小智 18

您可以使用中间件.

像这样的东西将检查用户auth每个请求:

class AuthRequiredMiddleware(object):
    def process_request(self, request):
        if not request.user.is_authenticated():
            return HttpResponseRedirect(reverse('landing_page')) # or http response
        return None
Run Code Online (Sandbox Code Playgroud)

文档: process_request

另外,不要忘记在settings.py中启用它

MIDDLEWARE_CLASSES = (
    ...
    'path.to.your.AuthRequiredMiddleware',
)
Run Code Online (Sandbox Code Playgroud)

  • 但该解决方案需要为每个视图指定登录 URL。OP 表示,他希望对所有视图的所有未经授权的请求都发生这种情况。 (5认同)
  • 这个答案有些过时了。对于当前版本的Django,最好在下面查看@AriG的答案。 (2认同)

Guy*_*ely 11

查看登录所需装饰的文档

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    ...
Run Code Online (Sandbox Code Playgroud)

另一个选择是将它添加到您的urls.py模式,请参阅此答案

urlpatterns = patterns('',
    (r'^foo/$', login_required(direct_to_template), {'template': 'foo_index.html'}),
)
Run Code Online (Sandbox Code Playgroud)

  • 这是我想避免的。将装饰器添加到我的所有视图并更改我的所有 url 操作。另一方面,我不想重定向到登录,而是重定向到另一个页面。如果用户愿意,可以从该页面登录离开。 (2认同)

IVI*_*IVI 11

从Django 1.10开始,自定义中间件类必须实现新的样式语法.您可以使用以下类来验证用户在尝试访问任何视图时是否已登录.

from django.shortcuts import HttpResponseRedirect


class AuthRequiredMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)
        if not request.user.is_authenticated():
            return HttpResponseRedirect('login')

        # Code to be executed for each request/response after
        # the view is called.

        return response
Run Code Online (Sandbox Code Playgroud)

  • 我认为您需要移动您的`self.get_response(request)`调用,以便在`request.user.is_authenticated()`检查之后进行。编写方式是,未经身份验证的请求将运行视图代码,该视图代码将生成响应,然后auth检查将使用重定向到登录页面的方式替换该响应。无论如何,视图代码中的任何更新/删除都应以权限检查为边界,但是最好不要冒险。 (2认同)

Mar*_*lén 9

这可以通过中间件来完成。

我发现了一个非常漂亮的 djangosnippet,它完全符合您的要求。你可以在这里找到它,它看起来像:

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)
Run Code Online (Sandbox Code Playgroud)

您所要做的就是将文件另存为middleware.py并将该类包含在您的 settings.py 中,即

MIDDLEWARE_CLASSES += ('projectname.common.middleware.RequireLoginMiddleware',)
Run Code Online (Sandbox Code Playgroud)

您还可以定义LOGIN_URLin settings.py,以便将您重定向到您的自定义登录页面。默认LOGIN_URL值为'/accounts/login/'.


Rok*_*iša 7

您可以login_url通过设置来避免指定LOGIN_URL

因此,settings.py补充:

LOGIN_URL = '<some_url>'
Run Code Online (Sandbox Code Playgroud)

并在您的views.py注释相关函数中仅使用@login_required

@login_required
def some_view_function(request):
Run Code Online (Sandbox Code Playgroud)

如果您需要视图函数中重定向,您可以使用:

return redirect_to_login(request.get_full_path())
Run Code Online (Sandbox Code Playgroud)


Ali*_*emi 5

也许为时已晚,但在 django 1.9+ 中这太简单了。Django为泛型类 引入了Login required mixin ,这是William S. Vincent的一个很好的例子

只需在您的视图中添加 LoginRequiredMixin 作为父类

from django.contrib.auth.mixins import LoginRequiredMixin

class BlogUpdateView(LoginRequiredMixin, UpdateView):
model = Post
template_name = 'post_edit.html'
fields = ['title', 'body']
Run Code Online (Sandbox Code Playgroud)

您也可以使用login_required 装饰器进行方法请求