【问题标题】:Adding auth decorators to flask restx将身份验证装饰器添加到烧瓶 restx
【发布时间】:2020-07-31 08:17:55
【问题描述】:

我有一个使用 flask-restxflask-login 的 Flask 应用程序。我希望默认情况下所有路由都需要登录,并明确定义不需要身份验证的公共路由。我已经按照这个问题中给出的示例开始使用装饰器:

Best way to make Flask-Login's login_required the default

它适用于函数端点,但不适用于restx 资源端点。

我尝试将函数添加为装饰器,并使用method_decorators 字段。例如:

def public_route(decorated_function):
    """
    This is a decorator to specify public endpoints in our flask routes
    :param decorated_function:
    :return:
    """
    decorated_function.is_public = True
    return decorated_function


class HelloWorld(ConfigurableResource):

    method_decorators = {"get": [public_route]}

    @public_route
    @api.doc('Welcome message')
    def get(self):
        return {'hello': 'world'}

这个测试通过了:

def test_hello_world_is_public():
    api = Namespace('health', description='Health related operations')
    hello = HelloWorld(api, config=None, logger=None)
    is_public_endpoint = getattr(hello.get, 'is_public', False)
    assert is_public_endpoint

我的挑战是我看不到如何在我的身份验证逻辑中访问此属性:


    @app.before_request
    def check_route_access():
        """
        This function decides whethere access should be granted to an endpoint.
        This function runs before all requests.
        :return:
        """
        is_public_endpoint = getattr(app.view_functions[request.endpoint], 'is_public', False)

        if person_authorized_for_path(current_user, request.path, is_public_endpoint):
            return
        # Otherwise access not granted
        return redirect(url_for("auth.index"))

这适用于普通函数端点,但不适用于 restx 资源。

我知道restx 将我的资源类包装在一个函数中,以便烧瓶可以进行调度,但我不知道如何从这里访问装饰器。所以我有一些问题:

  • 是否可以从 view_function 访问装饰器?
  • 能否知道端点是restx资源还是普通的rest函数?
  • 有没有更好的方法来实现我想要实现的目标?

【问题讨论】:

    标签: python flask flask-restplus flask-restx


    【解决方案1】:

    基于thisthismethod_decorators变量应该是一个函数列表,所以你应该像这样使用它:

    def _perform_auth(method):
        is_public_endpoint = getattr(method, 'is_public', False)
        # place the validation here
    
    class Resource(flask_restx.Resource):
        method_decorators = [_perform_auth]
    

    【讨论】:

    • 有没有办法在全局范围内应用该 method_decorator,这样我就不必将它放在每个资源上?我尝试将 perform_auth 函数添加到 Api 和 Namespace 的 decorators 参数中,但它似乎不起作用
    • 当然。您只需要从答案中描述的“资源”类继承所有资源类。
    【解决方案2】:

    是否可以从 view_function 到达装饰器?

    嗯...这是可能,但我不会推荐它。这是example

    是否可以知道端点是restx资源还是 普通的休息功能?

    您可能可以检查 func 并确定它是否来自 restx,也许可以查看 __qualname__,但话又说回来,我不会推荐它。

    有没有更好的方法来实现我想要实现的目标?

    我会选择以下解决方案之一:

    • 显式装饰需要身份验证的 view_func 和资源,而不是相反
    • 为公共端点创建蓝图,使用 before_request 装饰器为受保护端点创建蓝图以进行授权

    【讨论】:

      猜你喜欢
      • 2020-05-26
      • 2014-04-09
      • 1970-01-01
      • 2021-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      相关资源
      最近更新 更多