Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use Flask-Login's authentication as simple HTTP auth for a REST API?

Tags:

python

flask

Right now, my webapp has a full auth system implemented through Flask-Login. But say that I have this controller:

@app.route("/search_query")
@login_required
def search_query():
    query = request.args.get("query")
    return jsonify(search(query))

This works great when you login to the page and make searches against it, if you're authenticated it goes through, otherwise it routes you back to the login page (through an unauthorized_handler function).

@lm.unauthorized_handler
def unauthorized():
    return redirect(url_for("login"))

The problem is, I want to be able to use some form of simple HTTP authentication for this without having two separate auth systems so that I can make REST API calls against it. In short, I want to avoid having to use both Flask-Login and HTTPBasicAuth, and just use Flask-Login to achieve simple authentication, is this possible through Flask-Login?

like image 728
Stupid.Fat.Cat Avatar asked Oct 20 '22 00:10

Stupid.Fat.Cat


2 Answers

Use the flask-login's request_loader to load from request auth header. You don't need to implement the decorator yourself, and current_user will point to the user loaded.

Example:

login_manager = LoginManager()

@login_manager.request_loader
def load_user_from_header():
    auth = request.authorization
    if not auth:
        return None
    user = User.verify_auth(auth.username, auth.password):
    if not user:
        abort(401)
    return user

With that, you can mark a view as login required by:

@app.route('/user/info')
@login_required
def user_info():
    return render_template('user_info.html', current_user.name)
like image 150
Frost Ming Avatar answered Oct 22 '22 10:10

Frost Ming


If you looking for users to authenticate and make REST API calls they are going to have to send their credentials with every api call.

What you could do is a new decorator that checks for the auth header and authenticate the user.

Please refer to the entire app that I've posted on codeshare for more info: http://codeshare.io/bByyF

Example using basic auth:

def load_user_from_request(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if current_user.is_authenticated:
            # allow user through
            return f(*args, **kwargs)
        if auth and check_auth(auth.username, auth.password):
            return f(*args, **kwargs)
        else:
            return bad_auth()

    return decorated

With that code you can now decorate your views to check for the header.

@app.route("/search_query")
@load_user_from_request
def search_query():
    query = request.args.get("query")
    return jsonify(search(query))

you can curl my example app like this: curl --user [email protected]:secret http://0.0.0.05000/success

like image 32
m1yag1 Avatar answered Oct 22 '22 09:10

m1yag1