5
votes

I'm using Flask-Security to manage users, and I'm getting reports that users are logged-in successfully as themselves, but randomly when they load a page, it will show them logged as someone completely different. I'm not sure where I'm going wrong. What are possible ways this could happen?

I user a UserService to do some simple user management. I instantiate a user service before every request and pass in current_user.


@app.before_request
def load_request_services():
    g.user_service = UserService(user_datastore, application_service, email_service, ORGS, current_user)

Then, I get the current user in UserService from this method:


def current_user_get_info(self):
    return {
        'user': self.current_user.email,
        'first_name': self.current_user.first_name,
        'last_name': self.current_user.last_name,
        'phone_number': self.current_user.phone_number,
}

this is called when this API request code is executed:

    class CurrentUser(restful.Resource):
     def get(self):
         return json_response(g.user_service.current_user_get_info())
1
Do you ever play around with the session? session["userid"] is where Flask-Login/Security looks for the current user (source). So it might be worth starting from there, then working your way up through to the code you're created to find where you start noticing something odd.Doobeh
I don't play around with sessions. However, one thing I do is set remember_me=True when I call login_user and never enforce a fresh login. However, I do redeploy my app from time to time as I make updates. Will this screw up the session? If a user comes back to the site after a redeploy, will all the sessions be clear? I would assume the app stores the session information somewhere, and it would presumably be gone after a redeploy. However, I notice I don't have to relogin after a redeploy.vik
the app.secret_key is used to sign sessions, so if that stays the same between redeployments, your sessions would still be valid.Doobeh
A long shot: are you using Flask-Cache (or any other server cache) to cache your views?iurisilvio
I am not using Flask-Cache or any other cacheing. However, I did some reading on Flask and read that if you are in debug mode and there is an unhandled exception, Flask will keep the request context lying around for debugging. Since the site was being tested, I left debug mode on. If that's the case, perhaps it's some artifact of current_user proxy object and unpopped requests contexts. Can't be entirely certain but I shut off debug mode and will see what happens.vik

1 Answers

6
votes

I found the issue and am posting here for others who might have the same issue.

It turns out that the users who were accessing my site were behind a VPN with a proxy. The proxy was caching the pages along with the user's cookies. When one user makes request, the proxy would cache the page along with that user's cookie in the header. On the next user's request, the proxy would serve back the page with the first user's cookie and thus the second user would find himself as someone else.

See here for more info: https://code.google.com/p/doctype-mirror/wiki/ArticleHttpCaching

I solved it by setting the cache-control HTTP header to 'private' so that the proxy will not try to cache it. In Flask, it looks like this:

@app.after_request
def add_header(response):
    response.cache_control.private = True
    response.cache_control.public = False
    return response