Implementing the timeout

Scattered across the internet are a few examples that are no longer valid in 2021, when implementing Flask web apps in Python.

This is a short example to show something working in 2021.

See the following code that uses the @app.before_request function to implement the session timeout:

import datetime
from flask import Flask, session, g
from datetime import timedelta
from flask_login import current_user

app = Flask(__name__)


@app.before_request
def before_request():
    session.permanent = True
    app.permanent_session_lifetime = timedelta(minutes=60)
    flask.session.modified = True
    g.user = current_user

The code is compromises of some calls, the first being the session.permanent flag: this let’s Flask know that you need the session expiring. The other flag that the code calls is the flask.session.modified flag and this let’s Flask know that you only want the session to expire after 60 minutes of inactivity. The final line of code signals grabs the logged in user from flask_login and sets the global user for Flask.

Finally, remember that the flask-login module has a remember=True flag when logging in a user. Ensure this is set to ‘False’ otherwise the remember variable will override the session timeout.

Complete Example

Please see below for a complete example (adapted from Shekhar Gulati’s example Available Here):

from flask import Flask, Response, redirect, url_for, request, session, abort, g
from flask_login import LoginManager, UserMixin, \
                                login_required, login_user, logout_user, current_user

from datetime import timedelta

app = Flask(__name__)

# config
app.config.update(
    DEBUG = True,
    SECRET_KEY = 'secret_xxx'
)

# flask-login
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"


# silly user model
class User(UserMixin):

    def __init__(self, id):
        self.id = id
        self.name = "user" + str(id)
        self.password = self.name + "_secret"
        
    def __repr__(self):
        return "%d/%s/%s" % (self.id, self.name, self.password)


# create some users with ids 1 to 20       
users = [User(id) for id in range(1, 21)]


# some protected url
@app.route('/')
@login_required
def home():
    return Response("Hello World!")

 
# somewhere to login
@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']        
        if password == username + "_secret":
            id = username
            user = User(id)
            login_user(user)
            return redirect(request.args.get("next"))
        else:
            return abort(401)
    else:
        return Response('''
        <form action="" method="post">
            <p><input type=text name=username>
            <p><input type=password name=password>
            <p><input type=submit value=Login>
        </form>
        ''')


# somewhere to logout
@app.route("/logout")
@login_required
def logout():
    logout_user()
    return Response('<p>Logged out</p>')


# handle login failed
@app.errorhandler(401)
def page_not_found(e):
    return Response('<p>Login failed</p>')
    
    
# callback to reload the user object        
@login_manager.user_loader
def load_user(userid):
    return User(userid)


@app.before_request
def before_request():
    session.permanent = True
    app.permanent_session_lifetime = timedelta(minutes=1)
    session.modified = True
    g.user = current_user

if __name__ == "__main__":
    app.run()


Please note: example tested as working as of Flask-2.0.1 and Flask-Login-0.5.0. To Sign in use any username with the same username plus _secret as the password. An example would be the following:

username: test

password: test_secret

The timedelta is set at one minute, so after this time period it should automatically sign the user out of the web app.

For more tutorials please check out the tag links below: