pallets-eco / flask-session

Server side session extension for Flask
https://flask-session.readthedocs.io
BSD 3-Clause "New" or "Revised" License
490 stars 236 forks source link

Every page request generates new session entry in the 'sessions' table #205

Closed alex-valchuk closed 5 months ago

alex-valchuk commented 6 months ago

Just imagine how soon my production web hosting will down from a lack of space.

Lxstr commented 6 months ago

@alex-valchuk can you be more specific and provide a reproduction for me please so I can hunt this one down?

giuppep commented 5 months ago

I think that @alex-valchuk might be referring to requests not originating from a browser (e.g. curl)?

I observed this behaviour with our "health-check" endpoint: with each GET request Flask will create a new session object. If using flask-session this will result in a new row in the server db. If the TTL of the session is long enough, you'll quickly end up with a huge session table.

However, I am not sure this problem can be fixed from within flask-session, for I believe it is Flask that asks for a new session after each request. Unfortunately, when I looked into this issue, I wasn't able to find a way to tell Flask to exclude some endpoints from session creation, but this was a while ago, so things might have changed 🤷🏽

alex-valchuk commented 5 months ago

@alex-valchuk can you be more specific and provide a reproduction for me please so I can hunt this one down?

@Lxstr, I gave up storing a session in database and just use default mechanism with cookies. I did nothing special except following the instructions described in the documentation. Later I realized that I simply don't need the session in db for now.

Lxstr commented 5 months ago

Thanks @giuppep and @alex-valchuk. I think this is now solved on the development branch with the use of overriding the boolean evaluation that was being used to determine if a session is empty. It was previously seeing an empty session with only permanent set as not empty.

This could probably be something more specific like a __is_empty method but at least it's a start.

class ServerSideSession(CallbackDict, SessionMixin):
    """Baseclass for server-side based sessions."""

    def __bool__(self) -> bool:
        return bool(dict(self)) and self.keys() != {"_permanent"}