FastAPI Authentication with JWT (Step-by-Step) | Web Engineering Notes
FastAPI Authentication with JWT (Step-by-Step)
Feb 17, 2026
FastAPIJWTAuthentication
Introduction
If you're wondering how to create a JWT authentication system in FastAPI, this step-by-step guide will walk you through the complete process. You'll learn how to generate tokens, set expiration times, and protect API routes using JWT authentication.
How to create a JWT in FastAPI?
Lets create a JWT by following the step by step procedure below.
Step 1: Install the required libraries
To create a JWT authentication system we need to install the following third party libraries:
fastapi to build the FastAPI app
pydantic to define request body schema
uvicorn to run FastAPI server
python-dotenv to load environmental variables
pyjwt to encode and decode JWT
Install them by running the following command in the VScode terminal or PowerShell:
bash
Related Articles
FastAPI + SQLAlchemy Tutorial: Build a CRUD API Step-by-Step for Beginners
This tutorial teaches beginners how to build a CRUD API with FastAPI and SQLAlchemy. You’ll learn project setup, database connection, models, Pydantic schemas, CRUD functions, API routes, and testing using Swagger UI. By the end, you will have a fully functional backend API ready to use.
Next.js + FastAPI Tutorial: Connect Frontend to Backend Step-by-Step
In this tutorial, you will learn how to connect a Next.js frontend to a FastAPI backend. We will build a simple full-stack application where the frontend fetches data from an API and displays it in the UI. You will also learn how to handle CORS, fetch API data, and understand how frontend and backend communicate in modern web applications.
The datetime and timedelta modules will be used to set token expiry time.
The jwt module would be used to encode and decode JWT
The os and load_dotenv module will be used to load env variables from
The Depends function will be used for dependency injection in FastAPI.
The BaseModel will be used to define the schema.
The HTTPBearer and HTTPAuthorizationCredentials will be used to secure the protected routes.
The HTTPException module will be used to raise HTTP errors.
Step 3: Set a password to sign JWT
Create an .env file in the project root. Make a variable and set a string password inside just like the below example:
python
# In .env fileSECRET_KEY=your-secret-password
The above secret key is just for an example. You can choose a stronger one.
Step 4: Load the secret key from .env file
Load the secret key in the main.py using the following code.
python
load_dotenv()SECRET_KEY = os.getenv("SECRET_KEY")if not SECRET_KEY: raise ValueError("SECRET_KEY not set in environment")
Step 5: Set the Hashing Algorithm
Set the hashing algorithm to sign the token. The recommended algorithm is HS256.
python
ALGORITHM = "HS256"
Step 6: Set the expiry time for JWT
Set the JWT expiry time according to your own preference. After the expiry time the JWT would be invalid. Always set the expiry time according to your own preferences.
python
ACCESS_TOKEN_EXPIRE_MINUTES = 30
Step 7: Encode the payload
Lets create a python function that would take the user data and return a JWT.
This function will be used later in the /login route that would validate a user and return a JWT. Follow the step by step procedure below to create a /login route.
How to test a JWT in FastAPI endpoint?
In real work flow, the JWT is created when a user logs in with a user name and password. The backend validates the user’s credentials. If the credentials are valid, the endpoint will create a JWT. Let's create this workflow step by step in FastAPI.
Step 1: Create a fake user data
In production, user data is stored in a database, but here we will just simulate a fake user database using a python dictionary. You can also create it using the below example.
Note: This user data is just for demonstration. Always store user data in the database for production.
Step 2: Define a user login schema
Let's define a schema for our /login endpoint that requires a user name and a password to validate the incoming user.
python
class UserLogin(BaseModel): username: str password: str
Step 3: Create a /login endpoint
Lets create an actual /login endpoint that will validate the user and return a JWT.
python
app = FastAPI(title="Beginner-Friendly JWT Example")@app.post("/login")def login(request: UserLogin): """ Login endpoint: returns JWT token if username/password are correct """ user = fake_users_db.get(request.username) if not user or user["password"] != request.password: raise HTTPException(status_code=401, detail="Invalid username or password") token = create_access_token({"sub": user["username"]}) return {"access_token": token, "token_type": "bearer"}
Step 4: Test the /login endpoint
To test the /login endpoint run your FastAPI app using the following command in the terminal.Make sure you are in the correct directory before running the command.
python
uvicorn main:app --reload
After running the app follow the below steps to test the login route:
Open http://localhost:8000/docs in the browser
Click on /login endpoint.
Click on the Try it out button.
Edit the values of username and password fields.
Enter the fake_user_db username and password.
Click on Execute Button.
Now you can see below the Response body showing response like:
If you also see this, congrats to yourself. You have just built a JWT authentication system in FastAPI.
Note: If you see CORS error while sending a actual request from your frontend application, I recommend you follow this step by step guide on how to fix cors issues in FastAPI.
While the /login endpoint creates a JWT on user validation, the real use case of the JWT is when the same user wants to access protected routes that need a valid JWT.
In that case the user has to provide the same token in the request header while the backend server will try to decode it. On successful decode the backend would allow the user to access the protected route. Let's build this system step by step.
How to Decode a JWT in FastAPI?
Let's understand step by step how to decode JWT and allow only the verified user to access the protected routes.
Step 1: Verify the Token
Let’s create a function that would verify the JWT by decoding it using the same secret key. If it was signed by you the JWT would be successfully decoded.
python
security = HTTPBearer()def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)): """ Dependency to decode JWT and return current user """ token = credentials.credentials try: # Decode token payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) username = payload.get("sub") if username is None: raise HTTPException(status_code=401, detail="Invalid token payload") except jwt.ExpiredSignatureError: raise HTTPException(status_code=401, detail="Token expired") except jwt.InvalidTokenError: raise HTTPException(status_code=401, detail="Invalid token") # Fetch user from fake DB user = fake_users_db.get(username) if not user: raise HTTPException(status_code=401, detail="User not found") return user
Step 2: Create a protected route
Lets create an endpoint that requires a valid token to access.
The testing of this route is different from a normal route. In this case a valid token is required first to access it. Follow the procedure below step by step to access the protected route.
Run your app if not running, using the command below:
python
uvicorn main:app --reload
Open http://localhost:8000/docs
Test the login endpoint using the same step explained earlier.
Copy the value of access_token without quoted commas.
Find the Lock icon beside Protected Route.
Click on it and paste the token inside the Value: field.
Click the Authorize button and close it.
Now click on the Try it out button of the protected route.
Click the Execute button.
You should see the following response in the Response Body:
Congrats, we have just built a complete JWT authentication system in FastAPI.
You can also check the protected route by providing the wrong or tampered token. You must see the following response in the response body this time:
python
{ "detail": "Invalid token"}
Notice how providing invalid token would result in unauthorized access of protected routes.
Conclusion
In this guide, we built a complete JWT authentication workflow in FastAPI — from generating tokens during login to protecting routes using dependency injection. While this example uses a fake database, the same architecture applies to production systems with proper password hashing and database integration.