代码之家  ›  专栏  ›  技术社区  ›  Hide

特定路径的烧瓶中间件

  •  4
  • Hide  · 技术社区  · 6 年前

    我用python flask制作了api服务器restful。

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

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

    例如,这样的代码,

    [中间件.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)
    

    [应用程序.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)
    

    我插入 app.wsgi_app = Test(app.wsgi_app) 之前/文章。

    所以我希望只有 /article 将打印“gogo”,

    但每条路线都印着“gogo”。

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

    如何为特定路由应用中间件?(在本规范中,仅 /条款 )

    谢谢。

    1 回复  |  直到 6 年前
        1
  •  25
  •   Community CDub    5 年前

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

    (一) 使用python decorator:

    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...
    

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

    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)
    

    (四) 你也可以用 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)
    

    希望这有帮助。