JSON Web Tokens With Python APIs. Part 1. Creating the Token
By: Mike Wolfe
Tags: Jwt, API, Web Development, Software Development, Python

JSON Web Tokens With Python APIs

Part 1. Creating the Token

Photo by Ilya Pavlov on Unsplash

When designing and building an Application Programming Interface (API), security is something that the developer must have in mind. Without security, a malicious user could potentially gain access to sensitive data. That’s where JWTs or session cookies come in to play. Today, we will be using JSON Web Tokens. Essentially, these are compacted JSON objects that securely transmit data. For this tutorial, we will build an API that authenticates a user and creates a token.

Let’s Get Building

Before we can get started writing our Python code, we need to figure out what the database will look like. Below is some SQL code to help us get started.

The first table we create is the Users table. It holds basic user information as well as the hashed password and the salt value used for the password. Next, we create the Claims table. This table will hold a list of applications and their corresponding Guid’s. If you are looking at the JWT documentation, these claims will be known as private claims within the payload part of the token. The final table we will create is the UserClaims table that ties claims to a user.

With our authentication tables created, it’s time to write some Python code. The API will be written using Flask and SQLAlchemy. I’m not going to go into detail about setting these up in your environment, but here are some resources to help get started:

For this API, we will have two different endpoints. The first will be a POST request that adds a user to the database. The second will be a GET request that creates a JWT for the user.

Now that we have some endpoints, we can add some meat and potatoes to them. Looking at the “adduser” endpoint, we need to have code that will create a salt value to be used for when we hash the users password. For those who may not know, a salt is a unique value that we add to the end of the password which is then hashed using some sort of encryption method. Once we have the salt, the hashed password and the rest of the users basic information, we need to add it to the database.

The function above will achieve most of what we are looking for. It is by no means perfect, but it does accomplish some basic error handling. In the future, it would be nice to have it check for an existing email address and handle that issue accordingly. There are two helper functions left that are needed to complete the “addusers” endpoint.

Disecting the “DetermineSalt” function, it uses the “os” module to generate a string that is 32 random bytes longs. Analyzing the “HashPassword” function, we pass the users password and the newly created salt to it. Importing the “hashlib” module, we use the sha256 hashing module to hash the combined password and salt.

With the “adduser” endpoint built, we can move on to the endpoint that will login the user (basically create the jwt).

Like the “AddUser” function, the “UserLogin” function performs some basic error handling. In a nutshell, this function checks the database for the users email, then hashes the provided password with the stored salt to see if it matches the password hash in the database. There is one more helper function that is needed for this function to be complete.

As you probably guessed, this function does exactly what it’s name is. It creates the JWT. The function also takes a claims parameter that will be defined in Part 2. In order to create the token, we use a secret string (this can be whatever you want it to be). The token is encoded using HS256 which is HMAC with SHA-256. One final note is that the “jwt” module needs to be imported in order to encode the token. To install this module, use pip.

pip3 install pyjwt

Testing the Endpoints

Now that the code writing is complete, it’s time to see if our hard work has paid off. To test the API endpoints, we will use Postman. To test our “adduser” endpoint, we will add a JSON object to the raw body in Postman. It will look a little something like this.

{

"firstName": "Bob",

"lastName": "Smith",

"email": "mytestmemail@gmail.com"

"password": "testPassword!" }

When you add your hostname and the “adduser” URL to Postman, you should get results similar to this when you send the POST request.

Testing the “userlogin” endpoint will be a little similar except the JSON object we send will look like this.

{

"email": "mytestmemail@gmail.com"

"password": "testPassword!" }

After changing the URL in Postman to the “userlogin” endpoint and sending the request, your result will look something like this.

Just for fun, try out changing the password for the same email. If it worked, the results should return as this.

Something really cool worth checking out, is heading over to the website jwt.io and plugging in the token we received when we successfully requested a token. This site will decode the token and break down the different parts of it for you. It’s also a good way to tell if you have a valid token.

Final Thoughts

To sum things up, this API is by no means complete (nor perfect). There is still quite a bit of work to be done in order to use the token for authentication. A few of those todo’s are that we need to implement the token claims portion as well as implementing the authentication for the token. However, all that will be handled in Part 2. Therefore, until we meet again cheers!