我用python flask-restful制作了api服务器。
我的系统使用令牌身份验证来验证权限。
因此,我添加了用于验证令牌的中间件。
例如,这样的代码
[middleware.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
)
谢谢。
答案 0 :(得分:12)
有几种方法可以在特定端点之前添加自定义处理。
1):使用python装饰器:
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)
希望这会有所帮助。