全局设置所有页面都需要登录?
Posted
技术标签:
【中文标题】全局设置所有页面都需要登录?【英文标题】:Set all pages to require login, globally? 【发布时间】:2012-01-12 16:59:06 【问题描述】:我想将未经身份验证的用户的访问重定向到登录页面,之后应该将登录的用户重定向到最初请求的页面。
根据文档,使用 @user_passes_test
装饰器很容易实现这一点。但似乎我必须装饰每个视图,这太疯狂了,太多了,而且容易出错。
什么是全局开启这个功能的好方法(除了一小部分固定的视图,比如login
)?也就是说,将所有内容默认为仅登录 + 在需要时显式处理匿名查看。
【问题讨论】:
这个博客提供了你想要的,使用中间件:onecreativeblog.com/post/59051248/… 【参考方案1】:from django.shortcuts import redirect
from django.conf import settings
class LoginRequiredMiddleware:
def __init__(self, get_response):
self.get_response = get_response
self.login_url = settings.LOGIN_URL
self.open_urls = [self.login_url] + \
getattr(settings, 'OPEN_URLS', [])
def __call__(self, request):
if not request.user.is_authenticated \
and not request.path_info in self.open_urls:
return redirect(self.login_url+'?next='+request.path)
return self.get_response(request)
【讨论】:
【参考方案2】:我解决这个问题的方法是使用带有装饰器(或您需要的任何代码)的 mixin 类。虽然你必须记得调用super(Class, self).get(...)
函数,所以我想它毕竟没有那么不同。
另一方面,我发现有一组可以做不同事情的 mixin 非常适合获得一个非常简单的视图来做很多事情而无需太多代码。
编辑
这就是我在上一个项目中的做法:
class BaseAuthMixin(object):
def auth_check(self, user):
return True
def dispatch(self, request, *args, **kwargs):
if not self.auth_check(request.user):
from django.http import HttpResponseRedirect
from django.contrib.auth import logout
is_web = False
is_live = False
if hasattr(self, 'get_url_name'):
from django.core.urlresolvers import reverse
from django.core.urlresolvers import NoReverseMatch
try:
next = reverse(self.get_url_name(), kwargs=kwargs)
except NoReverseMatch:
next = ''
else:
next= '?next=' + next
logout(request)
redirect_url = settings.LOGIN_URL
redirect_url += next
return HttpResponseRedirect(redirect_url)
else:
return super(BaseAuthMixin, self).dispatch(request, *args, **kwargs)
class LoginRequiredMixin(BaseAuthMixin):
"""
Check if the view needs the user to be logged in.
"""
def auth_check(self, user):
if not super(LoginRequiredMixin, self).auth_check(user):
return False
else:
if hasattr(self, 'login_required'):
if self.login_required and not user.is_authenticated():
return False
return True
class MyDefaultMixin(LoginRequiredMixin):
"""
Mixin that inherits from all common view mixins.
"""
pass
然后视图类使用上述内容(我使用 Django 1.3 和基于类的视图):
from django.views.generic import TemplateView
class SomeViewClass(TemplateView, MyDefaultMixin):
# Used by 'LoginRequiredMixin' to check if a user has to be logged in
login_required = True
# Template for the Django TemplateView
template_name = "some_view_template.html"
您需要一个视图来处理登录(URL 位于settings.LOGIN_URL
),其中包含一个带有名为next
的隐藏字段的表单。该字段必须由上下文变量设置为登录成功后要转到的页面。
如果所有视图都继承自基本 mixin(我上面的代码中的 MyDefaultMixin
),它将自动检查用户是否已登录 iv 视图包含一个名为 login_required
的属性,并且该属性设置为 True
。
可能有更好的方法可以做到这一点,但这就是我所做的并且效果很好。
【讨论】:
你能说得更具体些吗?我不明白你在说什么。什么级别?什么混入? 感谢约阿希姆!一旦我有足够的业力,我会支持你的答案【参考方案3】:看看middleware。这些是在请求周期的各个点运行的函数,例如在调用每个视图之前。
由于您可能希望从中排除某些视图,因此我会查看例如csrf 中间件是如何工作的,以及 csrf_exempt 装饰器。
见[SOURCE]/django/views/decorators/csrf.py
和[SOURCE]/django/middleware/csrf.py
【讨论】:
以上是关于全局设置所有页面都需要登录?的主要内容,如果未能解决你的问题,请参考以下文章