← Back to Blog

JWT Authentication in Python: Flask and FastAPI Examples

March 24, 2026 3 min read By CodeTidy Team

The JWT Authentication Conundrum: Simplifying Security in Python

We've all been there - stuck in the never-ending loop of authentication and authorization, trying to balance security with usability. One common mistake we see is the misuse of JSON Web Tokens (JWTs) in Python applications. In this article, we'll explore the world of JWT authentication in Python, using Flask and FastAPI as our trusty guides.

Table of Contents

  • What is JWT Authentication?
  • PyJWT Library: The Swiss Army Knife of JWTs
  • Token Creation and Verification in Flask
  • FastAPI Authentication with JWTs
  • Middleware Patterns for JWT Authentication
  • Refresh Tokens: Because Security Matters

What is JWT Authentication?

JWT authentication is a token-based authentication mechanism that allows clients to verify their identity without sharing sensitive information. A JWT is a digitally signed token that contains a payload of user data, which can be verified by the server without needing to store any session state. We recommend using JWTs over traditional session-based authentication because they're stateless, scalable, and more secure.

PyJWT Library: The Swiss Army Knife of JWTs

The PyJWT library is the de facto standard for working with JWTs in Python. It provides a simple and efficient way to create, verify, and decode JWTs. Let's take a look at how to create a JWT using PyJWT:

import jwt

# Define the payload
payload = {'user_id': 1, 'username': 'john_doe'}

# Define the secret key
secret_key = 'my_secret_key'

# Create the JWT
token = jwt.encode(payload, secret_key, algorithm='HS256')

print(token)

This code creates a JWT with a payload containing the user's ID and username, signed with a secret key using the HS256 algorithm.

Token Creation and Verification in Flask

Now that we have our JWT, let's see how to use it in a Flask application. We'll create a simple login endpoint that returns a JWT upon successful authentication:

from flask import Flask, request, jsonify
import jwt

app = Flask(__name__)

# Define the secret key
secret_key = 'my_secret_key'

@app.route('/login', methods=['POST'])
def login():
    # Authenticate the user...
    user_id = 1
    username = 'john_doe'

    # Create the JWT
    payload = {'user_id': user_id, 'username': username}
    token = jwt.encode(payload, secret_key, algorithm='HS256')

    return jsonify({'token': token.decode('utf-8')})

To verify the token, we can create a decorator that checks the token's validity:

def authenticate(f):
    def decorated_function(*args, **kwargs):
        token = request.headers.get('Authorization')
        if token:
            try:
                payload = jwt.decode(token, secret_key, algorithms=['HS256'])
                return f(*args, **kwargs)
            except jwt.ExpiredSignatureError:
                return jsonify({'error': 'Token has expired'}), 401
            except jwt.InvalidTokenError:
                return jsonify({'error': 'Invalid token'}), 401
        return jsonify({'error': 'Missing token'}), 401
    return decorated_function

FastAPI Authentication with JWTs

FastAPI provides built-in support for JWT authentication using the fastapi.security module. Let's create a simple login endpoint that returns a JWT:

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
import jwt

app = FastAPI()

# Define the secret key
secret_key = 'my_secret_key'

# Define the OAuth2 scheme
oauth2_scheme = OAuth2PasswordBearer(tokenUrl='login')

@app.post('/login')
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
    # Authenticate the user...
    user_id = 1
    username = 'john_doe'

    # Create the JWT
    payload = {'user_id': user_id, 'username': username}
    token = jwt.encode(payload, secret_key, algorithm='HS256')

    return {'access_token': token, 'token_type': 'bearer'}

Middleware Patterns for JWT Authentication

To simplify JWT authentication in our applications, we can use middleware patterns to verify the token on every request. In Flask, we can use the before_request decorator:

@app.before_request
def authenticate():
    token = request.headers.get('Authorization')
    if token:
        try:
            payload = jwt.decode(token, secret_key, algorithms=['HS256'])
        except jwt.ExpiredSignatureError:
            return jsonify({'error': 'Token has expired'}), 401
        except jwt.InvalidTokenError:
            return jsonify({'error': 'Invalid token'}), 401
    else:
        return jsonify({'error': 'Missing token'}), 401

In FastAPI, we can use the Depends system to verify the token:

from fastapi import Depends

async def get_current_user(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, secret_key, algorithms=['HS256'])
        return payload
    except jwt.ExpiredSignatureError:
        raise HTTPException(status_code=401, detail='Token has expired')
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=401, detail='Invalid token')

Refresh Tokens: Because Security Matters

Refresh tokens are an essential part of JWT authentication. They allow clients to obtain a new JWT without needing to re-authenticate. We recommend using refresh tokens to improve the security of our applications.

Key Takeaways

  • Use JWTs for authentication because they're stateless, scalable, and more secure.
  • Use the PyJWT library to create, verify, and decode JWTs.
  • Implement token creation and verification in Flask and FastAPI using the examples above.
  • Use middleware patterns to simplify JWT authentication.
  • Use refresh tokens to improve the security of our applications.

FAQ

Q: What is the difference between JWT and session-based authentication?

A: JWT authentication is stateless and more secure, while session-based authentication stores session state on the server.

Q: How do I handle token expiration?

A: Use the jwt.ExpiredSignatureError exception to handle token expiration.

Q: Can I use JWTs with other authentication mechanisms?

A: Yes, JWTs can be used with other authentication mechanisms, such as OAuth and OpenID Connect.

AI agent tools available. The CodeTidy MCP Server gives Claude, Cursor, and other AI agents access to 60+ developer tools. One command: npx @codetidy/mcp