6

I want to be able to detect if a user has closed a browser since last logging into a Flask site. I have read that Flask sessions are supposed to expire on closing the browser, but the session data is stored on the server as far as I can tell and is persisting across browser sessions. How can I clear all session data when the user closes the browser?

mainapp.py:

@mainapp.route('/')
def home():
    if 'user_name' in session:
        logger.debug( 'Logged in as {0}'.format(escape(session['user_name'])))
    return render_template('home.html')

userviews.py:

@userviews.route("/login", methods=["GET", "POST"])
def login():
    form = LoginForm(request.form)
    if form.validate_on_submit():
        #get user from db
        session['user_name'] = user.user_name

setup.py:

app.secret_key = 'somethingreallysecret'
Don Smythe
  • 8,096
  • 14
  • 58
  • 100

4 Answers4

10

Because the flask session uses cookies, the data is persisted even if the user closes the window. You can track use closing the window with Flask-SocketIO.

If you want to remove a specific key from session:

from flask import session
from flask_socketio import SocketIO, emit
from flask.ext.login import current_user, logout_user

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

@socketio.on('disconnect')
def disconnect_user():
    logout_user()
    session.pop('yourkey', None)
Amin Alaee
  • 1,755
  • 16
  • 26
  • I accepted as it answered the question. However I have decided the slowing of performance by using SocketIO doesn't justify it's use just just to track users closing a browser. – Don Smythe May 15 '16 at 06:19
  • I don't get it. You mean the SocketIO "disconnect" signal is not working? – Amin Alaee May 15 '16 at 06:20
  • It works fine, what I find is that the whole app slows down when I use SocketIO. – Don Smythe May 15 '16 at 06:22
  • 1
    I don't know what type of application you're developing, but keeping a web socket open has its costs. If you really need to track the connection, then this is the only way. But if you can do it with a logout or something, that'd be cheaper both for client and server. – Amin Alaee May 15 '16 at 06:37
2

Unless you're explicitly setting session.permanent = True the session cookie should expire when the browser closes.

Reference: Flask documentation on session.permanent

qff
  • 4,965
  • 2
  • 32
  • 57
2

It seems that contrary to vanilla Flask, the sessions opened in Flask-session are permanent by default, from the documentation:

By default, all non-null sessions in Flask-Session are permanent.

So maybe try to set SESSION_PERMANENT=False?

  • Good answer. Note: the docs say that False is the default but that's not what I'm experiencing in my testing. Explicitly setting it to False works for me (your answer and my answers above). – Dan King Apr 12 '21 at 16:34
0

Per the docs (https://flask.palletsprojects.com/en/1.1.x/api/#flask.session.permanent):

permanent:

"If set to True the session lives for permanent_session_lifetime seconds. The default is 31 days. If set to False (which is the default) the session will be deleted when the user closes the browser."

In the block of code where you set your session variables include this line:

session.permanent = False

E.g.

@app.route("/login", methods=["GET", "POST"])
def login() -> "html":
    if request.method == "GET":
        return render_template(
            "login.html",
        )
    else:
        # Process login form...

        # ...then set session variable
        session.permanent = False
        session["username"] = "some value"
        return render_template(
            "some_secure_page.html",
        )
Dan King
  • 514
  • 9
  • 18