I'm trying to write a basic Flask app that limits the number of active logins a user can have, a la Netflix. I'm using the following strategy for now:
- Using Flask_Security
- store a
active_login_count
field for myUser
class. - every time a successful login request is completed, the app increases the
active_login_count
by 1. If doing so makes the count greater than the limit, it callslogout_user()
instead.
This is a bad solution, because if the user loses her session (closed the incognito mode without logging out), the app hasn't been able to decrement her login count, and so, future logins are blocked.
One solution is to store the sessions on the server, but I don't know how I would go about authenticating valid sessions. Flask_Sessions is something I'm looking into, but I have no idea how to limit the number of active sessions.
As per my understanding, in the default configuration, Flask generates new session cookies on every request to prevent CSRF attacks. How would I go about doing that?
There could be several ways off the top of my head you approach this, none of them striking a nice balance between simplicity and effectiveness:
One way could be to add a
last_seen
field to your User. Pick some arbitrary number(s) that could serve as a heuristic to determine whether someone is "active". Any sufficiently long gap in activity could trigger a reset of theactive_login_count
. This obviously has many apparent loopholes, the biggest I see at the moment being, users could simply coordinate logins and potentially rack up an unlimited number of active sessions without your application being any the wiser. It's a shame humans in general tend to use similar "logical" mechanisms to run their entire lives; but I digress... You could make this approach more sophisticated by trying to track the user's active ip addresses. Add anactive_ips
field and populate a list of (n) ips, perhaps with some browser information etc to try and fingerprint users' devices and manage it that way.Another way is to use an external service, such as a Redis instance or even a database. Create up to (n) session ids that are passed around in the http headers and which are checked every time the api is hit. No active session id, or if the next session id would constitute a breach of contract, no access to the app. Then you simply clear out those session ids at regular intervals to keep them fresh.
Hopefully that gives you some useful ideas.