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.
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()
.
I recommend you to use Flask-Security
. There is a tutorial about how to use it to security your API interface.