特定路由的烧瓶中间件
问题描述
我用 Python Flask-RESTful 制作了 API Server.
I made API Server with Python Flask-RESTful.
我的系统使用令牌认证来验证权限.
My system use token authentication for verify permission.
所以,我添加了用于验证令牌的中间件.
So, I added middleware for verify token.
比如这样的代码,
[中间件.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".
So I expect that only access to /article
will print "gogo", however every route print "gogo".
也许每条路由都经过中间件.
Maybe every route pass through with middleware.
如何为特定路由应用中间件?(在这段代码中,只有/article
)
How can I apply middleware for specific route? (In this code, only /article
)
解决方案
有几种方法可以在特定端点之前添加自定义处理.
There are a few ways how to add custom processing before specific endpoint.
1)使用python装饰器:
1) Using 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...
3) 使用中间件.只需在请求路径上添加条件即可.
3) Using middleware. Just add condition on request path.
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
在特定蓝图之前设置函数列表.
4) Also you can use before_request_funcs
to set list of functions before specific blueprint.
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)
希望这会有所帮助.
相关文章