104

I'm building a website with flask where users have accounts and are able to login. I'm using flask-principal for the loging in part and the role management. Is there a way of making the user's session expire after say 5 minutes or 10 minutes? I was not able to find that in flask documentation or, flask-principal's documentation.

I thought of a way of doing it by hand, set a variable server-side with a time tag at the moment of login and at the next action the user takes, the server verifies the time-delta on that timestamp and deletes the session.

Micah
  • 111,873
  • 86
  • 233
  • 325
verrochio
  • 1,592
  • 3
  • 13
  • 15
  • Do you want expire user session after inactivity of 5 or 10 minutes or simply expire irrespective of activity level? – codecool Aug 03 '12 at 13:53
  • for inactivity i will have to implement that. just to expire when the browser is closed, or 24 hours. It does not expire at all right now. – verrochio Aug 04 '12 at 14:40
  • 3
    To make a session expire relative to activity: http://stackoverflow.com/questions/19760486/resetting-the-expiration-time-for-a-cookie-in-flask – zengr Dec 22 '13 at 18:29

3 Answers3

159

flask sessions expire once you close the browser unless you have a permanent session. You can possibly try the following:

from datetime import timedelta
from flask import session, app

@app.before_request
def make_session_permanent():
    session.permanent = True
    app.permanent_session_lifetime = timedelta(minutes=5)

By default in Flask, permanent_session_lifetime is set to 31 days.

Marian
  • 14,759
  • 6
  • 32
  • 44
codegeek
  • 32,236
  • 12
  • 63
  • 63
  • 18
    I believe it is also true that your session will be reset if you change your `app.secret_key` and restart the server. – John Mar 24 '13 at 22:27
  • 19
    session.permanent is False by default: http://flask.pocoo.org/docs/api/#flask.session.permanent – Randy Syring Jun 11 '14 at 18:13
  • 1
    Do you know what gets called when the permanent_session_lifetime expires? – ramu Jun 30 '15 at 22:11
  • So only if I use session.permanent = True I have to explictly expire it when I want to. right? – ramu Aug 14 '15 at 19:03
  • To expire the session after a timedelta relative to the last request please see: http://stackoverflow.com/a/19795394/227884. @codegeek: Can you please update your answer with the link. Would be helpful. Thanks! – UltraInstinct Mar 16 '16 at 19:10
  • 6
    What is the reason of using `before_request` here instead of `before_first_request`? – srctaha Jan 16 '17 at 01:41
  • 1
    @srctaha I think maybe he want to refresh the expires every time people visit site – Tanky Woo May 22 '17 at 07:53
  • 2
    This is working perfectly! Any suggestion on how we can flash a message when the session expires? – dganesh2002 Aug 11 '17 at 23:37
  • 1
    how would we find out that a user is kicked out due to session timeout? – senaps Oct 07 '17 at 06:38
  • 1
    why is this session.permanent called permanent if the goal is to not make it permanent? – dtc Dec 17 '19 at 20:53
  • By doing this way, it's impossible to implement expiration for each request. For example, if user choose to remember me, if we want `permanent_session_lifetime` will persist for 30 days, if not, it's only 5 minutes. – TomSawyer Jan 09 '20 at 04:22
  • @dganesh2002 Have you find a way to interact with the session timeout? I need a way to flash a message or reroute the user after the session expires. – Peter Bejan Dec 16 '21 at 14:37
  • What should I do if a request is sent every second to refresh the session? I have tried setting ```app.config['SESSION_REFRESH_EACH_REQUEST'] = False``` and the session still gets refreshed. – cssstudent Oct 11 '22 at 06:41
  • @srctaha I believe that `before_request` is necessary to make it work for different clients. `before_first_request` only runs for the first request of the first client to this instance of the server. – THN Feb 08 '23 at 09:28
61

Yes, We should set

session.permanent = True
app.permanent_session_lifetime = timedelta(minutes=5)

But I don't think it should be set at app.before_request, This will lead to set them too may times.

The permanent_session_lifetime is a Basics Configuration, so it should be set at you configure the app:

 from datetime import timedelta
 app = Flask(__name__)
 app.config['SECRET_KEY'] = 'xxxxxxxxx'
 app.config['PERMANENT_SESSION_LIFETIME'] =  timedelta(minutes=5)

The session will created for each client, seperated from other clients. So, I think the best place to set session.permanent is when you login():

@app.route('/login', methods=['GET', 'POST'])
def login():
    #After Verify the validity of username and password
    session.permanent = True
SuperShoot
  • 9,880
  • 2
  • 38
  • 55
tinyhare
  • 2,271
  • 21
  • 25
  • 1
    For Apache-Airflow (which uses Flask) setting this in https://github.com/apache/incubator-airflow/blob/master/airflow/contrib/auth/backends/ldap_auth.py did not work for me. – Kyle Bridenstine Sep 20 '18 at 00:29
  • 1
    Update the link in the answer to the latest version: [Basics Configuration](http://flask.pocoo.org/docs/config/#PERMANENT_SESSION_LIFETIME) – Wavesailor Feb 05 '19 at 18:32
  • 1
    I use flask session with rooms and broadcasting etc. above solution however did not work for me. I would expect that after 5min the user is directly logged out and redirected to login page .... is this possible with permanent session? or Do I have to achieve this using db and storing the login date? – sqp_125 Jul 31 '20 at 15:45
  • Is it possible to set session lifetime per each session? Eg. I have different user types and I want admin users to have a session valid for 1 hour, and the rest for 24 hours. – umat Oct 10 '22 at 10:01
4

Using a slight modification on CodeGeek's answer, the decorator @before_first_request is enough to get flask to "remember" the session timeout. @before_request runs before EACH request, which is not necessary. I've tested this with different timeouts and it works.

The calls are explained here.

from datetime import timedelta
from flask import session, app

@app.before_first_request  # runs before FIRST request (only once)
def make_session_permanent():
    session.permanent = True
    app.permanent_session_lifetime = timedelta(minutes=5)
thedude
  • 597
  • 5
  • 5