Python / Flask - Using flask_restless with flask_h

2019-07-25 05:31发布

问题:

my objective in this question is to secure my API.

in my application, I'm using Flask and flask_restless's APIManager to provide CRUD API to my Person object.

code sample:

manager = APIManager(app, flask_sqlalchemy_db=db)
manager.create_api(Person, methods=['GET', 'POST', 'PATCH', 'DELETE'])

and also using flask_httpauth to protect my other routes like this:

@app.route('/auth/get-token')
@auth.login_required
def get_auth_token():
    token = g.user.generate_auth_token()
    return jsonify({'token': token.decode('ascii'), 'fullname': g.user.fullname})

I could not figure out how to use @auth.login_required with the apimanager to not make it respond to anonymous requests, I read in the documentation something about preprocessors but also couldn't find a way to use it with @auth.login_required decorator.

any help will be appreciated.

回答1:

Unfortunately, it looks like Flask-Restless currently does not officially support attaching view decorators to the routes it manages. There is an open issue to add this feature, and there is also another issue specifically requesting support for Flask-HTTPAuth.

There is yet a third issue, in which a user shows the technique to manually inject the decorators after Flask-Restless created its endpoints. The snippet from that user's example that adds a get_cache decorator is below:

manager = flask.ext.restless.APIManager(app, flask_sqlalchemy_db=db)
manager.create_api(Person, methods=['GET', 'POST', 'DELETE'])
manager.create_api(Person2, methods=['GET', 'POST', 'DELETE'])

# hackish view decoration:
for model in [Person, Person2]:
    model_route = '{0}api0.{0}api'.format(model.__name__.lower())
    app.view_functions[model_route] = get_cache(app.view_functions[model_route])

In your case, you would replace get_cache with auth.login_required.

Update: As discussed below in the comments, the argument in '{0}api0.{0}api' is the table name, so the above code will only work if table names are left for Flask-SQLAlchemy to generate. If the model has a custom table name, then use that instead of model.__name__.lower().



回答2:

I recommend you to use Flask-Security. There is a tutorial about how to use it to security your API interface.