Mik*_*keN 12 django django-authentication
如果我想确保一个视图被列为具有公共访问权限,是否有一个与@public_access等效的装饰器,它与@login_required相反,并且明确表示该视图应该始终可公开访问?
我想到的一个用例是自动向所有公共视图添加"@csrf_exempt",并在代码中清楚地表明视图应该是公共可访问的.
Ale*_*dev 11
不幸的是,Django目前没有内置的支持,让您在@login_required被意外遗忘时暴露敏感信息的风险.
这是我的一个项目的解决方案:
middleware/security.py:
def public(function):
"""Decorator for public views that do not require authentication
"""
orig_func = function
while isinstance(orig_func, partial): # if partial - use original function for authorization
orig_func = orig_func.func
orig_func.is_public_view = True
return function
def is_public(function):
try: # cache is found
return function.is_public_view
except AttributeError: # cache is not found
result = function.__module__.startswith('django.') and not function.__module__.startswith('django.views.generic') # Avoid modifying admin and other built-in views
try: # try to recreate cache
function.is_public_view = result
except AttributeError:
pass
return result
class NonpublicMiddleware(object):
def process_view_check_logged(self, request, view_func, view_args, view_kwargs):
return
def process_view(self, request, view_func, view_args, view_kwargs):
while isinstance(view_func, partial): # if partial - use original function for authorization
view_func = view_func.func
request.public = is_public(view_func)
if not is_public(view_func):
if request.user.is_authenticated(): # only extended checks are needed
return self.process_view_check_logged(request, view_func, view_args, view_kwargs)
return self.redirect_to_login(request.get_full_path()) # => login page
def redirect_to_login(self, original_target, login_url=settings.LOGIN_URL):
return HttpResponseRedirect("%s?%s=%s" % (login_url, REDIRECT_FIELD_NAME, urlquote(original_target)))
Run Code Online (Sandbox Code Playgroud)
settings.py:
MIDDLEWARE_CLASSES = (
#...
'middleware.security.NonpublicProfilefullMiddleware',
#...
)
Run Code Online (Sandbox Code Playgroud)
最后,查看代码:
from <projname>.middleware import publi
@public
def some_view(request):
#...
# Login required is added automatically
def some_private_view(request):
#...
Run Code Online (Sandbox Code Playgroud)
此外,您可能希望查看"自动装饰django项目的所有视图"博客文章
如前面提到的海报,默认情况下不需要登录.
但是,有时阻止登录用户的某些视图很有用 - 例如,登录用户无法使用网站的注册页面.在这种情况下,您可以根据现有的login_required装饰器执行类似的操作
from django.contrib.auth.decorators import user_passes_test
from django.conf import settings
LOGGED_IN_HOME = settings.LOGGED_IN_HOME
def login_forbidden(function=None, redirect_field_name=None, redirect_to=LOGGED_IN_HOME):
"""
Decorator for views that checks that the user is NOT logged in, redirecting
to the homepage if necessary.
"""
actual_decorator = user_passes_test(
lambda u: not u.is_authenticated(),
login_url=redirect_to,
redirect_field_name=redirect_field_name
)
if function:
return actual_decorator(function)
return actual_decorator
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6128 次 |
| 最近记录: |