【问题标题】:Flask middleware for specific route特定路由的烧瓶中间件
【发布时间】:2018-08-05 05:49:08
【问题描述】:

我用 Python Flask-RESTful 制作了 API Server。

我的系统使用令牌认证来验证权限。

所以,我添加了用于验证令牌的中间件。

比如这样的代码,

[中间件.py]

class Test(object):
    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        print("gogo")
        return self.app(environ, start_response)

[app.py]

from flask import Flask
from flask_restful import Api
from api.board import Article
from api.auth import Login, Register, RefreshToken
from middleware import Test


app = Flask(__name__)
api = Api(app)

api.add_resource(Login, '/login')
api.add_resource(Register, '/register')
api.add_resource(RefreshToken, '/refresh')

# middleware here
app.wsgi_app = Test(app.wsgi_app)
api.add_resource(Article, '/article')

if __name__ == '__main__':
    app.run(debug=True)

我在/article 之前插入app.wsgi_app = Test(app.wsgi_app)

所以我希望只有访问/article 会打印"gogo",但是每条路线都会打印"gogo"

也许每条路由都经过中间件。

如何为特定路由应用中间件? (在这段代码中,只有/article

【问题讨论】:

  • 为什么不能使用decorator
  • @DanilaGanchar 你能给我举个例子吗?

标签: python flask routes middleware


【解决方案1】:

有几种方法可以在特定端点之前添加自定义处理。

1)使用python装饰器:

from functools import wraps

def home_decorator():
    def _home_decorator(f):
        @wraps(f)
        def __home_decorator(*args, **kwargs):
            # just do here everything what you need
            print('before home')
            result = f(*args, **kwargs)
            print('home result: %s' % result)
            print('after home')
            return result
        return __home_decorator
    return _home_decorator


@app.route('/home')
@home_decorator()
def home():
    return 'Hello'

2) 使用before_request

@app.before_request
def hook():
    # request - flask.request
    print('endpoint: %s, url: %s, path: %s' % (
        request.endpoint,
        request.url,
        request.path))
    # just do here everything what you need...

3) 使用中间件。只需在请求路径上添加条件即可。

class Middleware:

    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        # not Flask request - from werkzeug.wrappers import Request
        request = Request(environ)
        print('path: %s, url: %s' % (request.path, request.url))
        # just do here everything what you need
        return self.app(environ, start_response)


@app.route('/home')
def home():
    return 'Hello'


app.wsgi_app = Middleware(app.wsgi_app)

4)您也可以使用before_request_funcs在特定蓝图之前设置功能列表。

api = Blueprint('my_blueprint', __name__)


def before_my_blueprint():
    print(111)


@api.route('/test')
def test():
    return 'hi'


app.before_request_funcs = {
    # blueprint name: [list_of_functions]
    'my_blueprint': [before_my_blueprint]
}

app.register_blueprint(api)

希望这会有所帮助。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2022-01-23
  • 2019-12-15
  • 1970-01-01
  • 2019-10-05
  • 1970-01-01
  • 1970-01-01
  • 2017-07-25
  • 2017-11-22
相关资源
最近更新 更多