Introduction
In this post we are going to see how to give users opportunity to remember their login credentials through cookie so that next time they try to login to the application do not require username and password for login.
In our previous tutorials we have seen how to login and logout from an application using the following examples:
Here we will store username and password into cookie.
As long as cookie contains such user’s valid username and password, user doesn’t need to enter any username and password. The user will be logged in to the application automatically.
What is cookie?
An http cookie is a small piece of data sent from a website and stored on the user’s computer by the user’s web browser while the user is browsing.
Cookies were designed to be a reliable mechanism for websites to remember stateful information or to record the user’s browsing activity.
Prerequisites
Python 3.7.4, Flask 1.1.1, MySQL 8.0.17, Windows 10 64 Bit
Creating MySQL table
Create a table called user in the MySQL database using the following structure.
The following table has user_id
, user_name
, user_email
, user_password
columns.
CREATE TABLE `user` (
`user_id` bigint NOT NULL AUTO_INCREMENT,
`user_name` varchar(45) DEFAULT NULL,
`user_email` varchar(45) DEFAULT NULL,
`user_password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Dumping User Details
We don’t want to create any new user through our application, so we will dump a user details using SQL statement.
The password field’s value is in the encrypted format, so the actual value is roy
.
insert into `user`(`user_id`,`user_name`, `user_email`, `user_password`)
values (1, 'Soumitra', 'sou@email.com', 'pbkdf2:sha256:150000$k1Ud5dzh$d0347f416e89ea486b33c988c9be65730329b2dd6d712f73c9920103a006a82e');
Creating Project Directory
Create a project root directory called python-flask-rest-api-login-logout-remember as per your chosen location.
We may not mention the project’s root directory name in the subsequent sections but we will assume that we are creating files with respect to the project’s root directory.
Configuring Application
We will configure application through flask framework.
Create a file called app.py with the below code.
Here we need to assign secret key otherwise session will not work in Python. The secret key, ideally, should be in encrypted format.
We have also configured the session timeout – 10 minutes because flask expires session once you close the browser unless you have a permanent session.
We have also configured maximum time 5 minutes for cookie for testing purpose. Ideally cookie is kept live for days to months. We have defined the cookie timeout in a global variable so that this variable can be used anywhere throughout the application.
from flask import Flask
from datetime import timedelta
app = Flask(__name__)
app.secret_key = "secret key"
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=10)
global COOKIE_TIME_OUT
#COOKIE_TIME_OUT = 60*60*24*7 #7 days
COOKIE_TIME_OUT = 60*5 #5 minutes
Database Configuration
We create the below db.py Python script to setup the MySQL database configurations for connecting to database.
We need to configure database connection with flask module and that’s why we have imported app module and setup the MySQL configuration with flask module.
Make sure to change the database configuration values according to your database setup.
from app import app
from flaskext.mysql import MySQL
mysql = MySQL()
# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = 'root'
app.config['MYSQL_DATABASE_DB'] = 'roytuts'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)
Handling Session, Cookie, Login, Logout
Now we will see how to handle user’s login logout with session and cookie.
We will create main.py script. This script handles Python login and logout example with remember me option using Flask and MySQL.
It defines all required URIs for performing login and logout operations.
It will also connect to MySQL database server and query the database to read.
Related Posts:
- Python flask login logout example
- Login logout example using Python Flask REST API
- jQuery AJAX based Login Logout using Python Flask MySQL
We have used login.html page as a template view for logging in to the system but for home or index page we have only displaying html text instead of using template page. If you want you can use html template page for home or index page also.
The important part is /submit
URI which is used to validate user credentials.
If login credentials are found in the cookie then you may validate or not against database. Here we have validated against database values.
If user logs in first time with remember me option then only we put into the cookie. Finally user redirected to the restricted area upon successful login.
import pymysql
from app import app, COOKIE_TIME_OUT
from db import mysql
from flask import flash, session, render_template, request, redirect, make_response
from werkzeug import generate_password_hash, check_password_hash
@app.route('/')
def index():
if 'email' in session:
username = session['email']
return 'Logged in as ' + username + '<br>' + "<b><a href = '/logout'>Click here to logout</a></b>"
return "You are not logged in <br><a href = '/login'></b>" + "click here to login</b></a>"
@app.route('/login')
def login():
return render_template('login.html')
@app.route('/submit', methods=['POST'])
def login_submit():
conn = None
cursor = None
_email = request.form['inputEmail']
_password = request.form['inputPassword']
_remember = request.form.getlist('inputRemember')
if 'email' in request.cookies:
username = request.cookies.get('email')
password = request.cookies.get('pwd')
conn = mysql.connect()
cursor = conn.cursor()
sql = "SELECT * FROM user WHERE user_email=%s"
sql_where = (username,)
cursor.execute(sql, sql_where)
row = cursor.fetchone()
if row and check_password_hash(row[3], password):
print(username + ' ' + password)
session['email'] = row[2]
cursor.close()
conn.close()
return redirect('/')
else:
return redirect('/login')
# validate the received values
elif _email and _password:
#check user exists
conn = mysql.connect()
cursor = conn.cursor()
sql = "SELECT * FROM user WHERE user_email=%s"
sql_where = (_email,)
cursor.execute(sql, sql_where)
row = cursor.fetchone()
if row:
if check_password_hash(row[3], _password):
session['email'] = row[2]
cursor.close()
conn.close()
if _remember:
resp = make_response(redirect('/'))
resp.set_cookie('email', row[2], max_age=COOKIE_TIME_OUT)
resp.set_cookie('pwd', _password, max_age=COOKIE_TIME_OUT)
resp.set_cookie('rem', 'checked', max_age=COOKIE_TIME_OUT)
return resp
return redirect('/')
else:
flash('Invalid password!')
return redirect('/login')
else:
flash('Invalid email/password!')
return redirect('/login')
else:
flash('Invalid email/password!')
return redirect('/login')
@app.route('/logout')
def logout():
if 'email' in session:
session.pop('email', None)
return redirect('/')
if __name__ == "__main__":
app.run()
Template View File
Below login.html page is created inside templates folder from where flask API by default picks up the view file.
We show any message, if found, in flash scope on the top of the page.
We populate the input fields if the value found in cookie.
<doctype html>
<title>User Login with remember me - Python Flask</title>
<h2>Login</h2>
<p>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</p>
<form method="post" action="/submit">
<dl>
<p>
<input name="inputEmail" value="{% if 'email' in request.cookies %} {{ request.cookies.get('email') }} {% endif %}" type="text" placeholder="Email" required>
</p>
<p>
<input name="inputPassword" value="{% if 'pwd' in request.cookies %} {{ request.cookies.get('pwd') }} {% endif %}" type="password" placeholder="Password" autocomplete="off" required>
</p>
<p>
<input name="inputRemember" checked="{% if 'rem' in request.cookies %} {{ request.cookies.get('rem') }} {% endif %}" type="checkbox" autocomplete="off">Remember Me</input>
</p>
</dl>
<p>
<input type="submit" value="Submit">
</p>
</form>
Enough coding… let’s move on to testing…
Testing the Application
Now navigate to the project directory and execute the command python main.py
, your server will start on default port 5000.
If you want to change the port then you can change the line app.run()
to app.run(port=5001)
, where 5001 is the new port.
Invalid Credentials
When you input incorrect email and password without remember me checkbox checked then you will see below error:
![python flask login logout with remember me option](https://roytuts.com/wp-content/uploads/2019/09/image-109.png)
Valid Credentials
When you input valid username and password (roy/roy) then you will get below output:
![python flask login logout with remember me option](https://roytuts.com/wp-content/uploads/2019/09/image-110.png)
Remember Me
When you give valid credentials and check the checkbox (Remember Me) and click on Submit button.
Next time you come back to login to application on same browser and if cookie has not been expired then you will see the input fields are automatically populated with credentials and you just need to click on Submit button to login.
![python flask login logout with remember me option](https://roytuts.com/wp-content/uploads/2019/09/image-111.png)
That’s all. Hope you got an idea on Python Flask login logout example with remember me option.
Source Code
Thanks for reading.