4Geeks logo
4Geeks logo

Courses

Explore our extensive collection of courses designed to help you master various subjects and skills. Whether you're a beginner or an advanced learner, there's something here for everyone.

Coding Bootcamp

Learn live

Join us for our free workshops, webinars, and other events to learn more about our programs and get started on your journey to becoming a developer.

Upcoming live events

Learning library

For all the self-taught geeks out there, here is our content library with most of the learning materials we have produced throughout the years.

It makes sense to start learning by reading and watching videos about fundamentals and how things work.

Data Science and Machine Learning - 16 wks

Full-Stack Software Developer - 16w

Search from all Lessons

LoginGet Started
← Back to Lessons
Edit on Github

Understanding JWT and how to implement a simple JWT with Flask

How API Authentication works
Implementing JWT in your project API

📹 Here is a video explaining the JWT authentication implementation using React.js, Context API and Python Flask.

Almost every API needs an authentication layer, and there are many ways to tackle that problem, today we are going to be implementing JWT token into our Flask API.

How API Authentication works

You can divide a standard authentication process in 5 main steps:

  1. The user writes its username and password on your website.
  2. The username and password gets sent to the backend API.
  3. The API looks for any record on the User table that matches with both parameters at the same time (username and password).
  4. If a user is found, it generates a token for that user and responds status_code=200 back to the front end.
  5. The front-end will use that token from now on to make any future request.

Autentication workflow

☝️ If you don't know what a token is, I would recomend this reading.

What is JWT?

There are many ways to create tokens: Basic, Bearer, JWT, etc. All of them are different in its nature but all of them result in the same output: A hash (a big alphanumeric token).

Type of tokenHow it looks
Basic Tokenecff2099b95ed507a27a4717ec78965d529cc346
Bearer TokenYWxlc2FuY2hlenI6NzE0YmZhNDNlN2MzMTJiZTk5OWQwYWZlYTg5MTQ4ZTc=
JWT TokeneyJhbGciOiJIUzI1NiIsInR5c.eyJzdWIiOFt2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpM

☝️ As you can see, JWT Tokens are bigger than the other two types of token.

JSON Web Token or JWT is an open standard to create tokens

This standard has become quite popular since it's very effective for Web Apps like Google APIs, where after the user authentication you make API requests.

JSON Web Token is a type of token that includes a structure, which can be decrypted by the server that allows you to authenticate the identity of the user of that application.

Why using JWT Token?

In a nutshell: JWT is an amazing alternative because Basic Token is to simple and easy to hack and Bearer Token it's harder to maintain because you have to store each token on the database.

With JWT Tokens you don't need a database, the token itself contains all the information needed.

Autentication workflow

Structure of the JWT Token

Autentication workflow

You may notice that the string is divided in three sections separated by a (.). Each section has it meaning:

Section name
HEADERThe first part stores the type of token and the encryption algorithm
PAYLOADThe second part has the data that identifies the user: it can be its ID, user name, etc.
SIGNATUREDigital signature, which is generated with the previous two sections, and it allows you to verify if the content has been modified.

Implementing JWT in your project API

We strongly recomend using JWT Extended library to implement JWT autentication in your Python Flask API, the process can be divided in the following steps:

1) Include the JWT library in your Flask App setup

1from flask_jwt_extended import JWTManager 2 3# you must already have this line in your project 4# you don't have to add it again. 5app = Flask(__name__) 6 7# Setup the Flask-JWT-Extended extension 8app.config["JWT_SECRET_KEY"] = "super-secret" # Change this "super secret" with something else! 9jwt = JWTManager(app)

2) Create one endpoint for generating new tokens

The endpoint should be a POST because you are creating tokens (POST is for creation).

1POST /token 2Content-type: application/json 3Body: 4{ 5 "username": "alesanchezr", 6 "password": "12341234" 7}

This is how the endpoint could look like in Python:

1from flask_jwt_extended import create_access_token 2# Create a route to authenticate your users and return JWT Token. The 3# create_access_token() function is used to actually generate the JWT. 4@app.route("/token", methods=["POST"]) 5def create_token(): 6 username = request.json.get("username", None) 7 password = request.json.get("password", None) 8 # Query your database for username and password 9 user = User.query.filter_by(username=username, password=password).first() 10 if user is None: 11 # the user was not found on the database 12 return jsonify({"msg": "Bad username or password"}), 401 13 14 # create a new token with the user id inside 15 access_token = create_access_token(identity=user.id) 16 return jsonify({ "token": access_token, "user_id": user.id })

3) Use the @jwt_required() decorator on private routes

Now... any endpoint that requires authorization (private endpoints) should use the @jwt_required() decorator.

You will be able to retrieve the authenticated user information (if valid) using the get_jwt_identity function.

1from flask_jwt_extended import jwt_required, get_jwt_identity 2# Protect a route with jwt_required, which will kick out requests 3# without a valid JWT present. 4@app.route("/protected", methods=["GET"]) 5@jwt_required() 6def protected(): 7 # Access the identity of the current user with get_jwt_identity 8 current_user_id = get_jwt_identity() 9 user = User.query.get(current_user_id) 10 11 return jsonify({"id": user.id, "username": user.username }), 200

Implementing JWT in your project Front-End

On the front-end side we need two main steps: Creating a new token (a.k.a: login) and appending the token to the headers when fetching any other private endpoints.

Create new token:

Based on the endpoints we build on earlier we have to POST /token with the username and password information in the request body.

1const login = async (username, password) => { 2 const resp = await fetch(`https://your_api.com/token`, { 3 method: "POST", 4 headers: { "Content-Type": "application/json" }, 5 body: JSON.stringify({ username: "joe", password: "1234" }) 6 }) 7 8 if(!resp.ok) throw Error("There was a problem in the login request") 9 10 if(resp.status === 401){ 11 throw("Invalid credentials") 12 } 13 else if(resp.status === 400){ 14 throw ("Invalid email or password format") 15 } 16 const data = await resp.json() 17 // save your token in the localStorage 18 //also you should set your user into the store using the setStore function 19 localStorage.setItem("jwt-token", data.token); 20 21 return data 22}

Fetch any private information

Let's suppose I am using the front-end application and I just logged in, but now I want to fech some private or protected endpoint:

1// assuming "/protected" is a private endpoint 2const getMyTasks = await (username, password) => { 3 // retrieve token form localStorage 4 const token = localStorage.getItem('jwt-token'); 5 6 const resp = await fetch(`https://your_api.com/protected`, { 7 method: 'GET', 8 headers: { 9 "Content-Type": "application/json" 10 'Authorization': 'Bearer '+token // ⬅⬅⬅ authorization token 11 } 12 }) 13 if(!resp.ok) throw Error("There was a problem in the login request") 14 15 else if(resp.status === 403){ 16 throw Error("Missing or invalid token"); 17 } 18 else{ 19 throw Error('Uknon error'); 20 } 21 22 const data = await resp.json(); 23 console.log("This is the data you requested", data); 24 return data 25 26}

That is it! As you can see it's very simple to integrate JWT into your application using Flask/Python, just three steps on the backend and two steps on the front-ent. For any questions you can contact me on twitter @alesanchezr or use the #public-support channel on 4Geeks Academy's Slack community.