2

I only want logged-in users to access my RESTfull API. I have been searching all over and couldn't find any source which tells me how to do it. Weird, because I think it's very common to protect data.

I am using a Flask project with Flask-login and flask-Restless. I CRUD my data through SQL-alchemy classes to access my MySQL database. I create my RESTfull api like:

api_manager = APIManager(app, flask_sqlalchemy_db=db)
api_manager.create_api(Items, methods=['GET', 'POST', 'DELETE', 'PUT'])

How should I restrict access to my RESTfull api for users who are not logged in, or can't I do it with flask-restless? If not, what should/could I better use?

I am trying out some techniques, so suggestions in any directions are welcome!

Thanks in advance


After some more playing around I have found a solution. It might not be the best but it does the trick without too much code:

@app.before_request
def before_request():
    if ('/api/' in str(request.url_rule)) && (not current_user.is_authenticated()):
        return redirect('/login')

Is this the right way to go? Adding Preprosessors is a lot of code for every possible HTTP request. https://flask-restless.readthedocs.org/en/latest/customizing.html#request-preprocessors-and-postprocessors

Waxyen Flax
  • 101
  • 3
  • 9

1 Answers1

0

It seems you achieve what you want by customizing Flask-Restless. You could use a preprocessor to intercept your API request.

Here is a snippet. Please, be aware that this is an untested snippet.

def auth_func(*args, **kw):
    if not current_user.is_authenticated():
        raise ProcessingException(description='Not authenticated!', code=401)

api_manager = APIManager(app, flask_sqlalchemy_db=db)
api_manager.create_api(Items, methods=['GET', 'POST', 'DELETE', 'PUT'], preprocessors=dict(POST=[auth_func]))

Similarly, you can register the preprocessor to your APIManager, enabling it for all API's.

api_manager = APIManager(app, flask_sqlalchemy_db=db, preprocessors=dict(POST=[auth_func]))
api_manager.create_api(Items, methods=['GET', 'POST', 'DELETE', 'PUT'])
Trein
  • 3,658
  • 27
  • 36
  • This will work. I just think this could be done better. Why? Now I'd have to add all HTTP methods to the preprosessors and say that the auth_func() should be executed. 'POST', 'GET_SINGLE', 'GET_MANY', 'PATCH_SINGLE' or 'PUT_SINGLE', 'PATCH_MANY' or 'PUT_MANY', 'DELETE_SINGLE' 'DELETE_MANY' This is a lot of code. – Waxyen Flax Oct 18 '15 at 12:29
  • So why don't you register the preprocessor to your `APIManager` then? When I first wrote my answer, I thought you would like a fine grain control over the API access. I updated my answer with the suggestion. – Trein Oct 19 '15 at 00:13
  • It is already much better. I still have to add an user authentication for every HTTP method (see previous comment). I still have the feeling that someone must use too much code for that and I am still looking for a better solution. – Waxyen Flax Oct 19 '15 at 00:26