FastAPI is a modern web framework for building APIs with Python. It is fast, easy to use, and provides native support for authentication using JSON Web Tokens (JWT). In this tutorial, we will walk through the process of setting up authentication with JWT in a FastAPI application.
What is JWT?
JSON Web Tokens (JWT) are a standard method for securely transmitting information between parties as a JSON object. They are compact, self-contained, and can be easily transmitted as a URL parameter, a cookie, or within an HTTP header. JWTs are commonly used for authentication and information exchange in web applications.
Setting up a FastAPI Application
First, let’s create a new FastAPI application and install the necessary dependencies:
pip install fastapi
pip install uvicorn
pip install pyjwt
Next, create a new Python file for your FastAPI application, for example main.py
, and import the required modules:
from fastapi import FastAPI
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
from typing import Optional
from datetime import datetime, timedelta
import jwt
Creating a User Model
Next, let’s define a user model using Pydantic to store user information. This model will be used for authentication and authorization:
class User(BaseModel):
id: int
username: str
email: str
password: str
In a real-world application, you would typically use a database to store user data and retrieve it when needed.
Generating JWT
We will now create a function to generate a JWT token when a user successfully logs in. The token will contain the user’s id and an expiration time:
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(hours=24)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, "SECRET_KEY", algorithm="HS256")
return encoded_jwt
In a real-world scenario, you should store the SECRET_KEY
securely and not hardcode it in your application.
Authenticating Users
Now, let’s create a route for user authentication where users can log in using their credentials:
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
# Authenticate user
user = authenticate_user(form_data.username, form_data.password)
if not user:
raise HTTPException(status_code=400, detail="Incorrect username or password")
access_token = create_access_token(data={"sub": user.id})
return {"access_token": access_token, "token_type": "bearer"}
In this route, we authenticate the user by checking their credentials against the database. If the credentials are correct, we generate a JWT token using the create_access_token
function and return it to the user.
Protecting Routes
To protect routes with authentication, you can use the OAuth2PasswordBearer
security dependency provided by FastAPI. Here’s an example of how you can use it to secure a route:
from fastapi import Depends
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@app.get("/users/me")
async def read_users_me(token: str = Depends(oauth2_scheme)):
# Verify token
try:
payload = jwt.decode(token, "SECRET_KEY", algorithms=["HS256"])
user_id = payload.get("sub")
user = get_user_by_id(user_id)
if user is None:
raise HTTPException(status_code=401, detail="Invalid token")
return user
except jwt.ExpiredSignatureError:
raise HTTPException(status_code=401, detail="Token has expired")
except jwt.InvalidTokenError:
raise HTTPException(status_code=401, detail="Invalid token")
In this route, we use the OAuth2PasswordBearer
dependency to extract the JWT token from the request header. We then decode the token using the jwt.decode
function and verify its contents. If the token is valid, we return the user’s information.
Conclusion
In this tutorial, we have walked through the process of setting up authentication with JWT in a FastAPI application. By following these steps, you can secure your API endpoints and authenticate users effectively. FastAPI provides built-in support for authentication and authorization, making it easy to implement secure web applications.
Wooo, what a great great Video !!!!!, Excellent I do appreciate it !!!, I've been developing softWare for 40 years ( since I was 14 ), few videos like this one !!, and I've watched lots !!!
why decode_token['expiry'] >= time.time()??
I have yet to see any tutorials about actual atheoriaztion and permissions in fastapi
Это отличное видео! Всё чётко и подробно!
Even if i post the wrong acces token in authorize , it still allows me to post.. what's wrong?
37:46
i wish it was more deep
thanks! ur explanation is crystal clear!
How does the server tell client side that a user is logged in?
Hey, Bek have just subscribed your channel for developing & learning software skiils,
I like your teaching skills that there is silent background music with your slowly teaching techniques & explanation + hands-on.
your videos on Django is on of the great Tutorial for me …!
Thanks man…
I immediately became your subscriber, when I saw your codes on GitHub didn't use OAuth, this is what I Need Thanks a lot buddy. Awesome
Tried multiple times but finally got the error: { "detail": "Invalid token or expired token." }
You have Done a Great Job
respect from Pakistan ❤
Excellent, I enjoyed this video very much!
@21.24 how come you are getting I'd 4 and 5 if you are posting Id 0?
This is friggin AWESOME
Can anyone help me out.
I have one doubt suppose you have 2 users (student and admin)how to use the generated token during login, only for the student specified tag user I logged in and it's methods and that token should not be able to be used by the admin methods,
To perform operations on admin again we need to create token for that.
hi bek,if i want to update user information using PUT method of a specific user,how can i use the token that was generated in login and user the same token in PUT method to represent that same user and update only the details of that specific user
Thank you man,it was a nice one,really learnt and understood what i was working on
In the last step, does it give an error if I slightly change the token pasted? Also how can I read data from the token once inside a function?