User Authentication with Python Flask and MySQL

In the following blog, I am going to demonstrate a Login system using Python Flask and MySQL. I’m also covering the basics of Flask and common practices.

 

Table of content

Introduction to Flask

If you are thinking of developing a web application in Python, then the first thing that comes into your mind is a framework, and if it is so, then the Flask is the answer to your question.

Flask is light-weight Python framework developed by “Armin Ronacher”. werkzeug WSGI toolkit and jinja2 template engines are the main pillars of the flask framework.

 

Understanding user authentication and why it is important?

We all undergo the process of authentication initially, whenever we try to navigate to any website or using any mobile Apps, Web applications.

Logins are the set of credentials, which provide the security to prevent unauthorized access to data, and also verify the user’s identity.

 

Let’s start

Let’s start by installing the necessary packages.

sudo apt install python3-virtualenv

Python3 comes with a venv module to create virtual environments, which are independent groups of Python libraries, one for each project. Packages installed for one project will not influence other projects.

pip3 install flask

The above command will install the Flask module in your project.

pip3 install flask-mysqldb

flask-mysqldb helps you to connect and interact with the MySQL database.

pip install flask-bcrypt

This module is used for password hashing.

 

Creating the main application file

create an app.py file in your project folder and write the following code.

from flask import Flask, render_template
app = Flask(__name__)

if __name__ == '__main__':
  app.run(host='127.0.0.1', port=8000, debug=True)

This code will host our application on 127.0.0.1 which is localhost with port number 8000. By default, the port number is 5000.

If you change to debug mode as True, the server will reload itself on code changes, you no need to restart the server after every change into the code.

 

Adding Routes

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def root():
  return render_template('login.html')

@app.route('/home')
def home():
  return render_template('home.html')

if __name__ == '__main__':
  app.run(host='127.0.0.1', port=8000, debug=True)

here, the (‘/’) route is bound with the login method, so whenever we navigate to that route the login method will render automatically. Same, with the home route.

 

Creating templates

create templates folder in your project and add all Html files to that folder because Flask will try to find your Html file in this folder.

  • Project Folder
    • app.py
    • templates
      • login.html
      • home.html

Login.html

<html>
<head>
    {% with messages = get_flashed_messages() %}  
    {% if messages %}  
          {% for message in messages %}  
               <p style="text-align: center; color: #9C27B0;">{{ message }}</p>  
          {% endfor %}  
    {% endif %}  
    {% endwith %}
</head>
<body>
    <div class="main">
        <p class="sign" align="center">Login</p>
        <form class="form1" action="{{url_for('authenticate')}}" method="POST">
            <input class="un " type="text" align="center" placeholder="Username" name="username" required>
            <input class="pass" type="password" align="center" placeholder="Password" name="password" required>
            <button class="submit" type="submit">Login</button>
        </form>
    </div>   
</body>
</html>

 

Home.html

<!DOCTYPE html>
<html lang="en">
<head>
   <title>Home</title>
</head>
<body>
   <form action="{{url_for('logout')}}" >
       <div class="main">
           <h2 style="text-align: center; margin-top: 25px; color: rgb(85, 12, 124); padding-top: 25px;">Welcome {{uname}}</h2>
           <button class="submit" type="submit" style="margin-top: 25px;">Logout</button>
       </div>
   </form>
</body>
</html>

Full source code for Login.html and Home.html is available on GitHub

 

Connection to the MySQL database

Add this code to app.py file

from flask_mysqldb import MySQL

app = Flask(__name__)

app.config['MYSQL_HOST'] ='localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = 'your password'
app.config['MYSQL_DB'] = 'name of your database'

mysql = MySQL(app)

 

Adding Authenticate Method

from flask_bcrypt import Bcrypt

import os

bcrypt = Bcrypt()

@app.route('/authentication',methods=['POST','GET'])

def authenticate():

   if request.method == 'POST':
       uname = request.form['username']
       passwrd = request.form['password']   

       cur = mysql.connection.cursor()
       cur.execute("SELECT username,password FROM user WHERE username=%s",[uname])
       user = cur.fetchone()
       temp = user[1]

       if len(user) > 0:
           session.pop('username',None)
           if (bcrypt.check_password_hash(temp,passwrd)) == True:  
               session['username'] = request.form['username']
               return render_template('home.html',uname=uname)
           else:
               flash('Invalid Username or Password !!')
               return render_template('login.html')
   else:
       return render_template('login.html')

if __name__ == '__main__':
    app.secret_key = os.urandom(24)
    app.run(host='127.0.0.1', port=8000, debug=True)

The check_password_hash of bcrypt will check the existing password hash against the currently generated password hash , In our case if temp and passwrd will match then it returns True . otherwise returns False.

session.pop() method is used to release a session variable . in our case “username is our session variable . so we will set it to None.

The Session data is stored on top of cookies and the server signs them cryptographically. For this encryption, a Flask application needs a defined SECRET_KEY.  app.secret_key = os.urandom(24) will return a 24 character long string of random numbers.

 

Adding Logout Method

@app.route('/logout')
def logout():
    session.clear()
    return render_template('login.html')

 

In this step, we will restrict a user to access URL to any other pages without login.

For e.g. If any user tries to access localhost:8000/home without login, we can put any error message and the user will remain to the login page.

from flask import Flask , render_template,request,url_for,redirect,session,flash,g

@app.before_request

def before_request():

g.username = None


if 'username' in session:

g.username = session['username']

@app.route('/home')

def home():
   if g.username:
       return render_template('home.html')
   else:
       return render_template('login.html')

Here we will check whether “username”  variable is set or not , if the variable is set to session then the user can move to the home page . otherwise user will remain navigate to login page

Here is the final code for app.py file

from flask import Flask,render_template,request,url_for,redirect,session,flash,g
from flask_mysqldb import MySQL
from flask_bcrypt import Bcrypt
import os

app = Flask(__name__)

app.config['MYSQL_HOST'] ='localhost'
app.config['MYSQL_USER'] = 'root'
app.config['MYSQL_PASSWORD'] = 'password'
app.config['MYSQL_DB'] = 'user'

mysql = MySQL(app)
bcrypt = Bcrypt()

@app.before_request
def before_request():
   g.username = None
   if 'username' in session:
       g.username = session['username']

@app.route('/')
def root():
   return render_template('login.html')

@app.route('/authentication',methods=['POST','GET'])
def authenticate():
   if request.method == 'POST':
       uname = request.form['username']
       passwrd = request.form['password']   
       cur = mysql.connection.cursor()
       cur.execute("SELECT username,password FROM user WHERE username=%s",[uname])
       user = cur.fetchone()
       temp = user[1]
       if len(user) > 0:
           session.pop('username',None)
           if (bcrypt.check_password_hash(temp,passwrd)) == True:  
               session['username'] = request.form['username']
               return render_template('home.html',uname=uname)
           else:
               flash('Invalid Username or Password !!')
               return render_template('login.html')
   else:
       return render_template('login.html')

@app.route('/home')
def home():
   if g.username:
       return render_template('home.html')
   else:
       return render_template('login.html')

@app.route('/logout')
def logout():
   session.clear()
   return render_template('login.html')

if __name__ == '__main__':
    app.secret_key = os.urandom(24)
    app.run(host='127.0.0.1', port=8000, debug=True)

 

Output

 

 

Full source code is available on GitHub

 

Conclusion

By following this article one can have basic knowledge of flask and also be able to accomplish basic tasks such as authentication for a web app.

I will try to cover more such topics in upcoming blogs

References

https://speckyboy.com/login-pages-html5-css/

https://www.maartenbaert.be/simplescreenrecorder/

Read More
Zeel Pandya Zeel Pandya June 16, 2020 0 Comments

Why We Love QuickDBD Tool for Database Design

In Software development, the very first and important step is designed Database schemas. Its blueprints of your database and represents the database structure, variable type, validate, etc.

There are too many Database Diagram tools available. But in my experience, we use QuickDBD tools for Database Diagrams. It’s really easy to design database diagrams and really the right tools for that. your need just types syntax and database diagram will be drawn on the right side. Also, we can collaborate with a team.

5 Reasons to use QuickDBD Tools.

1. Work Fluently

Software development time is too important. QuickDBD provides features to draw schemas without leaving the keyboard. it also provides whatever detail is required to show. Developers can also write comments for feature remainder.

2. Save Time

We use QuickDBD Tools for long provide it really helps and saves a lot of time because of just writing syntax and remaining tasks done. GUI tools will never interrupt your working flow. It’s really simple and easy. All formats are easy to simple for developers.

3. Easy Syntex

As beginners, We think writing syntax for Database? I suggest it is just a simple syntax it saves you a lot of time. If you love to write code, you really love to write Database.

The basic system used like create a table just type table name and us -(dash) for starting field name and type. There are also special characters PK, int, Date, etc. We use the # (Hash) sign to write any comment.

4. Collaborate

As you are a single or multiple architect designer of a system. We can share diagrams online. QuickDBD will help to collaborate features to share the same file and quick update with collaboration.

In our experience, we are sharing databases with 4 to 5 teams, Architect designer to developer. Also, We have a link to the developer for understanding the meaning for field and data type.

Whether are you single and team this feature definitely helps to make your project successfully collaborate with a team.

5. Provide Export Feature

QuickDBD provides easy to export any file format like ANSI SQL, MySQL, SQL Server, and PostgreSQL file. This feature really saves your lot of time. Also, provide features for database document export for reference purposes in PDF file format to PNG and SVG File. It makes your diagram and document look good and helps to communicate clearly.

Whether you’re a beginner or an experienced professional QuickDBD database schema generator is an excellent choice. Also helps to model database and create code for MySQL, PostgreSQL and SQL Server much more.

Arkay Apps have used the QuickDBD tool for the last 1 year. After the experience, our team makes database design, Database documentation, and software development tasks too easy and saves a lot of time. It also provides a free trial period for demo purposes.

Read More
Harsh Gor Harsh Gor January 31, 2020 0 Comments