User authentication with Flask-JWT

Martín Lamas
Trabe
Published in
3 min readSep 16, 2019
Photo by Simone Viani on Unsplash

In this story we’ll learn how to implement a JWT authentication in flask with the Flask-JWT library. All the code implemented is available at this github repository.

Starting the project

We’ll start the project from scratch, so the first step will be to initialize it and install some required dependencies using pipenv:

$ mkdir jwt-auth-test-project
$ cd jwt-auth-test-project
$ pipenv --three
$ pipenv install flask flask-jwt flask-sqlalchemy

We’ll use the flask-sqlalchemy ORM library to manage the user data from the database.

Before continuing it’s recommended that we spawn a shell within the virtualenv running the following command:

$ pipenv shell

Next, we’ll create a python package that will contain the application source files:

mkdir jwtauthtest
touch jwtauthtest/__init__.py

Then we’ll place the following code in the jwtauthtest/__init__.py file in order to initialize the flask application:

Now, we’ll add a sample view function in the jwtauthtest/views.py file:

At this point we’ll have a basic flask application that will serve us as a starting point to continue. To test the application we must run the following commands:

$ export FLASK_APP=jwtauthtest
$ flask run

Next, open the http://localhost:5000/hello URL in your favourite browser to check that everything is ok :)

Configuring the database

Now we are going to configure the database. First, we’ll create the jwtauthtest/database.py file with the following code:

As we can see, the jwtauthtest.models module is imported. This module must contain the user model that holds the user data:

Finally, we’ll add the database initialization code in the jwtauthtest/__init__.py file:

The app.teardown_appcontext decorator registers a function to be called when the flask application context ends. We’ll use this decorator to close the database session.

Adding users

At this point we have a basic flask application that supports the users management in the database. Before implementing the JWT authentication, we should code a script to add a new user to the database. Let’s go!

First, install the click and the passlib libraries as dependencies:

$ pipenv install click passlib

We’ll use these libraries to implement the script as a command line utility and to store the passwords as secure hashes, respectively. Now, create the useradd.py file and add the following code:

Then, to add a user we can run this script manually:

python useradd.py

We’ll be prompted for the username and the password, and then a new user will be created into the database.

Implementing the JWT authentication

Now, we are going to implement the JWT authentication. The Flask-JWT library handles the process of token generation, decoding and signing for us.

First, we’ll create the jwtauthtest/jwt.py file with the following code:

As we can see, an instance of JWT class is created. We pass the flask application instance and the authentication and identity handlers as constructor parameters. These handlers specify the identity handler functions.

The authentication handler receives two positional arguments: the username and the password. If the authentication is successful, then an authenticated entity object must be returned.

The identity handler receives the JWT payload. Just like the authentication handler, an authenticated entity object must also be returned by this function.

Choosing a strong secret key is important because this key is used to sign the JWT tokens.

Finally, this module must be imported in the jwtauthtest/__init__.py file:

Authenticating the view functions

As the last step we are going to authenticate the view functions. Just import the jwt_required decorator and annotate the view functions with it:

Testing the application

At this point, we’ll have an authenticated flask application with JWT. Now, we are going to make an authenticated request to test the application. First, we’ll need to get a new JWT token. It’s easy with curl:

$ curl -X POST -H "Content-Type: application/json" http://localhost:5000/auth -d '{ "username": "admin", "password": "mysupersecretpassword" }'

Then we can make the authenticated request with the returned JWT token:

$ curl -X GET -H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1Njc0OTcyNjEsImlhdCI6MTU2NzQ5Njk2MSwibmJmIjoxNTY3NDk2OTYxLCJpZGVudGl0eSI6MX0.GncHdTHADlkeXYggn03nnmaS4tCYGNryHP6MQD7NywE" http://localhost:5000/hello

If everything is ok, we should see a Hello world! in our terminal :)

Summing up

Flask is a great web application framework designed to get you started quickly and easily. We can use it to develop small and lightweight projects, but also complex ones.

The Flask-JWT library provides a way to manage the authentication process when we need to use JWT tokens in our flask applications.

--

--