Implementing Non-persistent and Persistent Session in Flask
A guide to creating Non-persistent and Persistent sessions in Flask.
Let’s first create a simple web app. Our app will look like:-
Flow of the app will be:-
When you visit
/
or/home
, you will land at the home page./about
and/contact
are protected endpoints. When you visit/about
or/contact
If you are not signed-in, you will be redirected to login page. After successful login, a session is created and you will return to the page from where you have come from.
If you are a signed-in user, you will be redirected to the respective page.
When you visit
/products
, you will arrive at the products page. No sign-in is required to access this page.When you click on the
Sign In
button, a sign-in form will open. After successful login, a session is created and you will be redirected to the Home page.Clicking the
Log Out
button ends the session and logs the user out of the web app.
Now open VS Code and set up the folders and files as shown below:-
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web App</title>
<style>
.navbar {
display: flex;
align-items: baseline;
column-gap: 15px;
background-color: antiquewhite;
}
h2 {
margin: 0;
}
a {
text-decoration: none;
}
p {
margin: 0px 0px 0px 35vw;
}
</style>
</head>
<body>
<div class="navbar">
<h2>MyApp</h2>
<a href="{{ url_for('home') }}">Home</a>
<a href="{{ url_for('about') }}">About</a>
<a href="{{ url_for('contact') }}">Contact</a>
<a href="{{ url_for('products') }}">Products</a>
<a href="{{ url_for('login') }}"><button>Sign In</button></a>
<a href="{{ url_for('logout') }}"><button>Log Out</button></a>
{% if session["user_name"] %}
<p>Welcome {{session["user_name"]}}!</p>
{% endif %}
</div>
<hr>
{% block content %}
{% endblock %}
</body>
</html>
home.html
{% extends "index.html" %}
{% block content %}
<main>
<h3>You are at the home page!!</h3>
</main>
{% endblock %}
about.html
{% extends "index.html" %}
{% block content %}
<main>
<h3>You are at the About page!!</h3>
</main>
{% endblock %}
contact.html
{% extends "index.html" %}
{% block content %}
<main>
<h3>You are at the Contact page!!</h3>
</main>
{% endblock %}
products.html
{% extends "index.html" %}
{% block content %}
<main>
<h3>Below are the products that we offer.</h3>
<ul>
<li>Sofas</li>
<li>Chairs</li>
<li>Tables</li>
<li>Swings</li>
</ul>
</main>
{% endblock %}
login.html
{% extends "index.html" %}
{% block content %}
<main>
<h3>Please fill the below form to sign-in!!</h3>
<form action="{{ url_for('login') }}" method="post">
<input type="text" value="{{next}}" name="next" hidden>
<div>
<label for="username">Username</label>
<input type="text" id="username" name="username">
</div>
<div>
<label for="password">Password</label>
<input type="password" id="password">
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
</main>
{% endblock %}
Non-persistent Session using client-side session
If you use client-side sessions then the session info is stored in cookies in the web browser. If session.permanent = False
(which is the default in client-side session) then the session will be deleted when the user closes the browser.
Unless you're explicitly setting session.permanent = True
to make session persist, the session cookie will expire when the browser closes.
Note:- If the user only closes the tab (where the web app was open) and then reopens the app after some time, the session will not be deleted.
from flask import Flask, session, request, redirect, render_template, url_for
app = Flask(__name__)
app.config["SECRET_KEY"] = "supersecretkey" # Required for session security
@app.route('/')
@app.route('/home')
def home():
print("Session data is: ", session)
return render_template('home.html')
@app.route('/about')
def about():
# checking whether a user is logged in or not
if "user_name" not in session:
return redirect(url_for('login') + f"?next={request.url}")
return render_template('about.html')
@app.route('/contact')
def contact():
# checking whether a user is logged in or not
if "user_name" not in session:
return redirect(url_for('login') + f"?next={request.url}")
return render_template('contact.html')
@app.route('/products')
def products():
return render_template('products.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
next_url = request.args.get("next")
if request.method == 'POST':
# creating session data during login
# session.permanent = False # this is by default
session["user_name"] = request.form.get('username')
session["lang"] = "en"
session["theme"] = "dark"
next_url = request.form.get("next")
return redirect(next_url if next_url!='None' else url_for("home"))
return render_template('login.html', next=next_url)
@app.route('/logout')
def logout():
session.clear() # clears the session data
return "Signed Out!!!"
if __name__ == '__main__':
app.run(debug=True)
Now open the flask server and visit the web app by clicking the link http://127.0.0.1:5000/.
You will arrive at the home page. Click the Sign In button and log in. Once you are logged in, a non-persistent client-side session will be created. Now close the browser and open the web app again. You will find that the previous session has ended, and you are no longer signed in.
Click the Sign In button again and log in. This time, make sure you have other tabs open as well. Now, just close the web app tab. After a few minutes, open the web app again in another tab. You will find that the previous session has been restored, and you are still signed in.
Non-persistent Session using server-side session
The sessions opened in Flask-Session are permanent by default. To make non-persistent session, you must explicitly set app.config["SESSION_PERMANENT"] = False
or session.permanent = False
.
from flask import Flask, session, request, redirect, render_template, url_for
from flask_session import Session # Required for server-side session
app = Flask(__name__)
app.config["SECRET_KEY"] = "supersecretkey" # Required for session security
app.config["SESSION_TYPE"] = "filesystem"
app.config['SESSION_PERMANENT'] = False
Session(app)
@app.route('/')
@app.route('/home')
def home():
print("Session data is: ", session)
return render_template('home.html')
@app.route('/about')
def about():
# checking whether a user is logged in or not
if "user_name" not in session:
return redirect(url_for('login') + f"?next={request.url}")
return render_template('about.html')
@app.route('/contact')
def contact():
# checking whether a user is logged in or not
if "user_name" not in session:
return redirect(url_for('login') + f"?next={request.url}")
return render_template('contact.html')
@app.route('/products')
def products():
return render_template('products.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
next_url = request.args.get("next")
if request.method == 'POST':
# creating session data during login
# session.permanent = False
session["user_name"] = request.form.get('username')
session["lang"] = "en"
session["theme"] = "dark"
next_url = request.form.get("next")
return redirect(next_url if next_url!='None' else url_for("home"))
return render_template('login.html', next=next_url)
@app.route('/logout')
def logout():
session.clear() # clears the session data
return "Signed Out!!!"
if __name__ == '__main__':
app.run(debug=True)
Persistent Session using client-side session
In Flask, client-side sessions are non-persistent by default. To make them persistent, you need to set session.permanent = True
. By default, Flask sets permanent_session_lifetime
to 31 days. If you want the session to last for a specific number of seconds or minutes of user inactivity, you can change this value.
In the code below, I have set up a session that lasts for 5 minutes of user inactivity.
Note:- If a user remains active within the permanent_session_lifetime
period, their session remains valid. If the user is inactive for longer than the permanent_session_lifetime
, then only session expires.
from flask import Flask, session, request, redirect, render_template, url_for
from datetime import timedelta
app = Flask(__name__)
app.config["SECRET_KEY"] = "supersecretkey" # Required for session security
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=5)
@app.route('/')
@app.route('/home')
def home():
print("Session data is: ", session)
return render_template('home.html')
@app.route('/about')
def about():
# checking whether a user is logged in or not
if "user_name" not in session:
return redirect(url_for('login') + f"?next={request.url}")
return render_template('about.html')
@app.route('/contact')
def contact():
# checking whether a user is logged in or not
if "user_name" not in session:
return redirect(url_for('login') + f"?next={request.url}")
return render_template('contact.html')
@app.route('/products')
def products():
return render_template('products.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
next_url = request.args.get("next")
if request.method == 'POST':
session.permanent = True
# creating session data during login
session["user_name"] = request.form.get('username')
session["lang"] = "en"
session["theme"] = "dark"
next_url = request.form.get("next")
return redirect(next_url if next_url!='None' else url_for("home"))
return render_template('login.html', next=next_url)
@app.route('/logout')
def logout():
session.clear() # clears the session data
return "Signed Out!!!"
if __name__ == '__main__':
app.run(debug=True)
Now open the flask server and visit the web app by clicking the link http://127.0.0.1:5000/.
You will arrive at the home page. Open the Cookies section under the "Application" tab in the developer tools. Click the Sign In button and log in. Once you are logged in, a persistent client-side session will be created that lasts for 5 minutes of user inactivity. Sit idle for 5 minutes, then refresh the page. You will find that the session has ended and you are automatically logged out.
Persistent Session using server-side session
from flask import Flask, session, request, redirect, render_template, url_for
from datetime import timedelta
from flask_session import Session # Required for server-side session
app = Flask(__name__)
app.config["SECRET_KEY"] = "supersecretkey" # Required for session security
app.config["SESSION_TYPE"] = "filesystem"
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=5)
Session(app)
@app.route('/')
@app.route('/home')
def home():
print("Session data is: ", session)
return render_template('home.html')
@app.route('/about')
def about():
# checking whether a user is logged in or not
if "user_name" not in session:
return redirect(url_for('login') + f"?next={request.url}")
return render_template('about.html')
@app.route('/contact')
def contact():
# checking whether a user is logged in or not
if "user_name" not in session:
return redirect(url_for('login') + f"?next={request.url}")
return render_template('contact.html')
@app.route('/products')
def products():
return render_template('products.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
next_url = request.args.get("next")
if request.method == 'POST':
# creating session data during login
session["user_name"] = request.form.get('username')
session["lang"] = "en"
session["theme"] = "dark"
next_url = request.form.get("next")
return redirect(next_url if next_url!='None' else url_for("home"))
return render_template('login.html', next=next_url)
@app.route('/logout')
def logout():
session.clear() # clears the session data
return "Signed Out!!!"
if __name__ == '__main__':
app.run(debug=True)
Thank you for your time! 😊
Connect with me on LinkedIn