Django视图的@login_required装饰器的对面是什么? [英] What is the opposite of @login_required decorator for Django views?

查看:181
本文介绍了Django视图的@login_required装饰器的对面是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我想确保一个视图被列为具有公共访问权限,那么是否有一个相当于@public_access的装饰器,这将与@login_required相反,并且明确表示该视图应该始终公开访问? p>

我想到的一个用例是自动将@csrf_exempt添加到所有公共视图中,除了在代码中清楚视图应该是可公开访问的。 / p>

解决方案

不幸的是,Django目前没有内置的支持,让您在 @login_required 被意外忘记。



这是我的一个项目的解决方案:



middleware / security.py

  def public (函数):
不需要身份验证的公共视图的装饰器

orig_func = function
while isinstance(orig_func,partial): #如果部分使用原始功能授权
orig_func = orig_func.func
orig_func.is_public_view = True

返回函数

def is_public(function) :
try:#cache found
return function.is_public_view
except AttributeError:#cache not found
result = function .__ module __。startswith('django。')而不是函数.__模块__。startswith('django.views.generic')#避免修改管理员和其他内置的视图

尝试:#尝试重新创建缓存
function.is_public_view = result
除了AttributeError:
pass

返回结果


类非公共中间件(对象):

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 - 使用原始函数进行授权
view_func = view_func.func

request.public = is_public(view_func)
如果不是is_public(view_func):
如果request.user.is_authenticated():#只需要扩展检查
return self.process_view_check_logged(request,view_func,view_args,view_kwargs )

return self.redirect_to_login(request.get_full_path())#=>登录页面

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 / p>

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

,最后查看代码:

  from< projname> .middleware import publi 

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

#需要自动添加登录
def some_private_view(request):
#...
/ pre>

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


If I want to make sure that a view is listed as having public access, is there a decorator equivalent to @public_access which would be the opposite of @login_required and make it clear that the view should be publicly accessible always?

One use case I have in mind is to automatically add "@csrf_exempt" to all public views in addition to making it clear in the code that the view should be publicly accessible.

解决方案

Unfortunately, there's currently no built-in support for this in Django, leaving you at risk of exposing sensitive info when @login_required is accidentally forgotten.

Here's a solution from one of my projects:

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',
    #...
)

and, finally, view code:

from <projname>.middleware import publi

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

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

Also, you may want to look at "Automatically decorating all views of a django project" blog post

这篇关于Django视图的@login_required装饰器的对面是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆