【问题标题】:Is using view decorators to handle user permissions bad practice?使用视图装饰器来处理用户权限是不好的做法吗?
【发布时间】:2019-07-15 11:16:17
【问题描述】:

我正在使用 Django 视图装饰器以相当复杂的方式检查权限,并且开始意识到这可能是一种不好的做法。

假设用户的个人资料处于某种状态,比如说“申请待定”,因此某些视图不应显示给该用户,而应该显示给“申请完成”的用户。我目前正在使用装饰器将待处理的用户重定向到主页,并弹出一个告诉他们他们的应用程序仍处于待处理状态的弹出窗口。

但是,我在google's python best practice 上读到,装饰器应该很简单,而不是依赖于数据库连接、文件等。

这是否意味着在显示视图之前检查借款人应用程序的状态是不好的做法,如果是,还有什么替代方法?

【问题讨论】:

    标签: python django security


    【解决方案1】:

    在 Django 中,使用 user_passes_testpermission_required 装饰器是正确的做法。

    from django.contrib.auth.decorators import user_passes_test, permission_required
    
    @user_passes_test(lambda user: user.is_superuser)
    @permission_required('your_perm')
    def my_view(request):
        # code
    

    【讨论】:

      【解决方案2】:

      你提到的文字充其量是值得商榷的——至少在它的表述上:

      避免装饰器本身的外部依赖(例如,不要依赖文件、套接字、数据库连接等),因为它们在装饰器运行时可能不可用(在导入时,可能来自 pydoc 或其他工具) .

      (...)

      装饰器是“顶级代码”的特例

      这仅适用于装饰器函数的“外部”部分,而不是装饰器返回的包装函数内的代码(通常),即:

      def mydecorator(func):
          print("""
             this is the outer decorator code 
             and will be executed when the decorator
             is applied (most often - but not necessarily
             - at import time)
             """
             )
             def wrapper(*args, **kw):
                 print("""
                    this is the inner decorator code     
                    which is only executed when the
                    decorated function is called,
                    so here it's safe to do whatever
                    you would do in the decorated function.
                    """
                    )
                    return func(*args, **kw)
            return wrapper       
      

      IOW,您正在做的事情(在视图中使用装饰器来检查是否允许用户访问内容)不仅完全没问题,而且是装饰器用途的规范示例,甚至是官方的处理方式这在 Django 中,参见 Davide Pizzolato 的回答。

      【讨论】:

      • 谢谢,我明白我现在是如何误读了。在这种逻辑变得非常复杂的情况下,是否有一种模式可以推荐以避免if user.profile.application.is_submitted and not user.profile.contract.signed or user..... 之类的事情,或者是将这些布尔权限/用户状态值集中在用户模型本身上以维护 DRY 原则等的最简单方法开。
      • 抱歉,但您的评论中的问题没有万能的答案,因此需要更多的上下文来提供一些可能的解决方案。您可能需要考虑将其作为一个适当的问题发布(提供尽可能多的上下文)。
      猜你喜欢
      • 1970-01-01
      • 2014-01-21
      • 2011-10-01
      • 1970-01-01
      • 2016-02-26
      • 2018-12-12
      • 1970-01-01
      • 2017-01-13
      • 1970-01-01
      相关资源
      最近更新 更多