当前位置:  开发笔记 > 后端 > 正文

与Django视图的@login_required装饰器相反的是什么?

如何解决《与Django视图的@login_required装饰器相反的是什么?》经验,为你挑选了2个好方法。

如果我想确保一个视图被列为具有公共访问权限,是否有一个与@public_access等效的装饰器,它与@login_required相反,并且明确表示该视图应该始终可公开访问?

我想到的一个用例是自动向所有公共视图添加"@csrf_exempt",并在代码中清楚地表明视图应该是公共可访问的.



1> Alexander Le..:

不幸的是,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)))

settings.py:

MIDDLEWARE_CLASSES = (
    #...
    'middleware.security.NonpublicProfilefullMiddleware',
    #...
)

最后,查看代码:

from .middleware import publi

@public
def some_view(request):
    #...

# Login required is added automatically
def some_private_view(request):
    #...

此外,您可能希望查看"自动装饰django项目的所有视图"博客文章



2> LS55321..:

如前面提到的海报,默认情况下不需要登录.

但是,有时阻止登录用户的某些视图很有用 - 例如,登录用户无法使用网站的注册页面.在这种情况下,您可以根据现有的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

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有