0% found this document useful (0 votes)
156 views8 pages

JWT For User Authentication in Flask

This document provides instructions for setting up user authentication in a Flask application using JSON Web Tokens (JWTs). It describes creating a virtual environment, installing dependencies, defining a database model with SQLAlchemy, and implementing routes for registration, login, and getting all users by passing a JWT in the request header. The code defines a token_required decorator to verify tokens and get the current user object, and issues tokens on login that expire after 30 minutes.

Uploaded by

Leon
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
156 views8 pages

JWT For User Authentication in Flask

This document provides instructions for setting up user authentication in a Flask application using JSON Web Tokens (JWTs). It describes creating a virtual environment, installing dependencies, defining a database model with SQLAlchemy, and implementing routes for registration, login, and getting all users by passing a JWT in the request header. The code defines a token_required decorator to verify tokens and get the current user object, and issues tokens on login that expire after 30 minutes.

Uploaded by

Leon
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 8

geeksforgeeks.

org

Using JWT for user authentication in Flask


Pre-requisite: Basic knowledge about JSON Web Token (JWT)
I will be assuming you have the basic knowledge of JWT and how JWT works. If not, then I
suggest reading the linked Geeksforgeeks article.

Let’s jump right into the setup. Ofcourse, you need python3 installed on your system. Now, follow
along with me. I will be using a virtual environment where I will install the libraries which is
undoubtedly the best way of doing any kind of development.

 First create a folder named flask project and change directory to it. If you are on linux then
type the following in your terminal.

mkdir "flask project" && cd "flask project"

 Now, create a virtual environment. If you are on linux then type the following in your
terminal.

python3 -m venv env

Note: If you get any error then that means venv isn’t installed in your system. To install it, type
sudo apt install python3-venv in your terminal and then you are good to go. If you are on windows
then use something like virtualenv to make a virtual environment.

This will create a folder named venv in the flask project which will contain the project specific
libraries. 

 Now create a file named requirements.txt and add the following lines in it.

Flask-RESTful==0.3.8
PyJWT==1.7.1
Flask-SQLAlchemy==2.4.1

 Now, lets install these libraries for this project. To do so, first we need to activate the virtual
environment. To do so, type the following in your terminal.

source env/bin/activate

Note: If you are on windows then it would be Scripts instead of bin


Now, its time to install the libraries. To do so, again type the following in your terminal. 

pip install -r requirements.txt

Now, we are done with the setup part. Lets now start writing the actual code. Before beginning with
the code, I would like to make something clear. I would be writing the entire code in a single file,
i.e. the database models and the routes all together, which is not a good practice and definitely not
manageable for larger projects. Try keeping creating separate python files or modules for routes and
database models.
With that cleared out, lets directly jump into the writing the actual code. I will be adding inline
comments explaining every part of the code.
Create a python file called app.py and type the following code in it. 

 Python3

Python3
from flask import Flask, request, jsonify, make_response

from flask_sqlalchemy import SQLAlchemy

import uuid

from  werkzeug.security import generate_password_hash, check_password_hash

import jwt

from datetime import datetime, timedelta

from functools import wraps

app = Flask(__name__)

app.config['SECRET_KEY'] = 'your secret key'

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

db = SQLAlchemy(app)

class User(db.Model):

    id = db.Column(db.Integer, primary_key = True)

    public_id = db.Column(db.String(50), unique = True)

    name = db.Column(db.String(100))

    email = db.Column(db.String(70), unique = True)

    password = db.Column(db.String(80))

def token_required(f):

    @wraps(f)

    def decorated(*args, **kwargs):

        token = None

        if 'x-access-token' in request.headers:

            token = request.headers['x-access-token']

        if not token:

            return jsonify({'message' : 'Token is missing !!'}), 401


        try:

            data = jwt.decode(token, app.config['SECRET_KEY'])

            current_user = User.query\

                .filter_by(public_id = data['public_id'])\

                .first()

        except:

            return jsonify({

                'message' : 'Token is invalid !!'

            }), 401

        return  f(current_user, *args, **kwargs)

    return decorated

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

@token_required

def get_all_users(current_user):

    users = User.query.all()

    output = []

    for user in users:

        output.append({

            'public_id': user.public_id,

            'name' : user.name,

            'email' : user.email

        })

    return jsonify({'users': output})

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

def login():

    auth = request.form

    if not auth or not auth.get('email') or not auth.get('password'):

        return make_response(

            'Could not verify',


            401,

            {'WWW-Authenticate' : 'Basic realm ="Login required !!"'}

        )

    user = User.query\

        .filter_by(email = auth.get('email'))\

        .first()

    if not user:

        return make_response(

            'Could not verify',

            401,

            {'WWW-Authenticate' : 'Basic realm ="User does not exist !!"'}

        )

    if check_password_hash(user.password, auth.get('password')):

        token = jwt.encode({

            'public_id': user.public_id,

            'exp' : datetime.utcnow() + timedelta(minutes = 30)

        }, app.config['SECRET_KEY'])

        return make_response(jsonify({'token' : token.decode('UTF-8')}), 201)

    return make_response(

        'Could not verify',

        403,

        {'WWW-Authenticate' : 'Basic realm ="Wrong Password !!"'}

    )

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

def signup():

    data = request.form

    name, email = data.get('name'), data.get('email')

    password = data.get('password')

    user = User.query\
        .filter_by(email = email)\

        .first()

    if not user:

        user = User(

            public_id = str(uuid.uuid4()),

            name = name,

            email = email,

            password = generate_password_hash(password)

        )

        db.session.add(user)

        db.session.commit()

        return make_response('Successfully registered.', 201)

    else:

        return make_response('User already exists. Please Log in.', 202)

if __name__ == "__main__":

    app.run(debug = True)

Now, our code is ready. We now need to create the database first and then the table User from the
ORM (Object Relational Mapping). To do so, first start the python3 interpreter in your terminal.
You can do that by typing python3 in your terminal and that should do the trick for you.

Next you need to type the following in your python3 interpreter:

from app import db


db.create_all()

So, what this does is first it imports the database object and then calls the create_all() function to
create all the tables from the ORM. It should look something like this.
Now that our actual code is ready, let’s test it out. I recommend using postman for testing out the
APIs. You can use something like CURL but I will be using postman for this tutorial.

To start testing our api, first we need to run our API. To do so, open up a terminal window and type
the following in it. 

python app.py

You should see an output like this 

If you get any error then make sure all your syntax and indentation are correct. You can see that our
api is running on http://localhost:5000/. Copy this url. We will use this urlalong with the routes to
test the api.
Now, open up Postman. You should be greated with the following screen.
Now, click on the + sign and enter the url localhost:5000/signup change request type to POST, then
select Body and then form-data and enter the data as key-value pair and then click on Send and you
should get a response. It should look something like this. 

So, we are registered. Now lets login. To do that just change the endpoint to /login and untick the
Name field and click on Send. You should get a JWT as a response. Note down that JWT. That will
be our token and we will need to send that token along with every subsequent requests. This token
will identify us as logged in.
The JSON contains the token. Note it down. Next try to fetch the list of users. To do that, change
the endpoint to /user and then in the headers section, add a field as x-access-token and add the JWT
token in the value and click on Send. You will get the list of users as JSON.

You might also like