龙卷风,如果未提供令牌,如何使用 401 删除 POST/GET

Tornado, how to drop POST/GET with 401 if a token is not provided

如果 header 中未提供令牌字段,我想放弃 GET/POST 请求。

目前我使用this code (from GitHub Gist):

def require_basic_auth(handler_class):
    def wrap_execute(handler_execute):
        def serve_error(handler, status):
            handler._transforms = []  # necessary
            handler.set_status(status)
            handler.finish()

        def _execute(self, transforms, *args, **kwargs):
            expected_header = self.request.headers.get('X-User-Auth')

            if expected_header is None:
                return serve_error(self, 403)

            kwargs['token'] = expected_header
            # Token validation is done in the `post(self, token)` method

            return handler_execute(self, transforms, *args, **kwargs)

        return _execute

    handler_class._execute = wrap_execute(handler_class._execute)

    return handler_class

两个问题:

  1. 它修补了一个 _method,我有点不习惯操作名称以 _
  2. 开头的方法
  3. 它导致未捕获的异常错误:AttributeError: '_NullFuture' object has no attribute 'add_done_callback'

稍作阅读,我发现 .prepare() 方法可能是实现它的最佳方式。但是我还没有在 .prepare().

中找到任何关于如何正确执行此操作的示例

谁能告诉我如何做这个的例子?


编辑 1

我忘了补充:上面的装饰器还方便地将 header 提取到 token kwarg 中,以供 post(self, token) 方法使用。如果使用 prepare(self).

,我不确定该怎么做

是的,直接修补 Tornado 的 RequestHandler 并不理想。

使用 Tornado,您应该为处理程序创建一个基础 class。这个基础 class 就像在其他框架(Django、Flask 等)中看到的“中间件”

Tornado 的另一种模式是创建“mixin”classes,这对于将通用功能插入特定处理程序很有用。

这是我在项目中所做的:

class BaseHandler(web.RequestHandler):
    def prepare(self):
        expected_header = self.request.headers.get('X-User-Auth')
        
        if not expected_header:
            return self.send_error(401)

        # ... other common logic to run before other methods ...


# Inherit your handlers from BaseHandler everywhere
class MyHandler(BaseHandler):
    def get(self):
        pass