Zeh*_*ort 5 python flask python-3.x flask-restful flask-jwt-extended
我正在尝试构建一个 RESTful API 应用程序flask_restful,flask_jwt_extended用于用户授权并将flask_limiter用户的配额限制为 6/分钟。我的玩具/测试代码如下(尚未实施实际的授权方案):
from flask import Flask, make_response
from flask_restful import Api, Resource
from flask_limiter import Limiter
from werkzeug.exceptions import HTTPException
from flask_jwt_extended import jwt_required, create_access_token, JWTManager, get_jwt_identity
# custom HTTP exception
class OutOfQuota(HTTPException):
code = 402
name = 'Out Of Quota'
app = Flask(__name__)
limiter = Limiter(app, key_func=get_jwt_identity)
api = Api(prefix='')
class Token(Resource):
def get(self, user):
return make_response({'token': create_access_token(identity=user)})
class Test(Resource):
@jwt_required
@limiter.limit('6/minute')
def get(self):
return make_response({'message': f'OK {get_jwt_identity()}'})
api.add_resource(Token, '/token/<string:user>')
api.add_resource(Test, '/test')
api.init_app(app)
# custom error handler (change "Payment Required" to "Out Of Quota" HTTP status
@app.errorhandler(429)
def ratelimit_handler(e):
return OutOfQuota(f'quota limit exceeded: {e.description}')
jwt = JWTManager(app)
app.config['JWT_SECRET_KEY'] = 'nothing-fancy-for-now'
if __name__ == '__main__':
app.run(host='localhost', port=8080)
Run Code Online (Sandbox Code Playgroud)
端点/token为用户生成一个 JWT 令牌,其用户名作为 JWT 身份存储在其中。当/test使用此令牌访问端点时,我想检查此特定用户(即此特定身份)访问此端点的次数,因此使用get_jwt_identityaskey_func的Limiter。
/test问题是当我运行上面的代码时访问端点时没有任何限制;我可以根据需要多次、快速地访问它。我在这里错过了什么吗?
我遇到了类似的问题,并找到了一个似乎有效的解决方案。Flask-Restful做事有点不同。它创建可插入视图。文档中有一个Flask-Limiter关于这种特殊情况的部分 - https://flask-limiter.readthedocs.io/en/stable/#using-flask-pluggable-views
class Test(Resource):
decorators = [limiter.limit("5/minute")]
def get(self):
...
Run Code Online (Sandbox Code Playgroud)
我们不需要通过 提供装饰器@limiter.limit,而是需要以这种方式提供它。
我也有一个关于从哪里获取参考的问题limiter。在某些基目录中,您可以实现它并导入到您的类中。
from flask import Flask
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
_app = Flask(__name__)
limiter = Limiter(
_app,
key_func=get_remote_address
)
Run Code Online (Sandbox Code Playgroud)