Leapcell: The Best of Serverless Web Hosting
Implementing Authentication with JWT in FastAPI
Introduction
In modern web application development, authentication is a crucial part of ensuring system security. JSON Web Token (JWT), as an open standard based on JSON (RFC 7519), is widely used in single sign-on (SSO) scenarios for distributed sites due to its compactness and security. FastAPI is a high-performance web framework based on Python. This article will introduce how to use JWT for authentication in FastAPI, combined with the given JWT implementation code.
Basics of JWT
What is JWT?
JSON Web Token (JWT) is designed to transmit claims between network application environments. It is compact and secure, especially suitable for single sign-on scenarios in distributed sites. JWT claims are often used to transmit the authenticated user identity information between the identity provider and the service provider to obtain resources from the resource server, and can also add other claim information required by business logic. This token can be directly used for authentication or encrypted.
Composition of JWT
JWT consists of three segments of information:
- Header: Usually declares the file type and encryption algorithm.
- Payload: Records the data to be transmitted in JSON format.
- Signature: A signature used for verification.
base64UrlEncode Method
When generating a JWT, the base64UrlEncode
method is used for the signature. The basic functions of this method are as follows:
- Input a UTF-8 encoded string
s1
. - Encode the string
s1
using base64 to get the strings2
. - If there are equal signs at the end of
s2
, remove all equal signs at the end. - If there are plus signs (
+
) ins2
, replace all plus signs with minus signs (-
). - If there are slashes (
/
) ins2
, replace all slashes with underscores (_
).
The following is the Python code to implement this method:
import hmac
import base64
from hashlib import sha256
from urllib import parse as urlp
def b64url(str1):
if type(str1) == str:
return str(base64.b64encode(str1.encode('utf-8')), encoding="utf-8").strip('=').replace('+', '-').replace('/', '_')
elif type(str1) == bytes:
return str(base64.b64encode(str1), encoding="utf-8").strip('=').replace('+', '-').replace('/', '_')
else:
raise TypeError("The type of given argument must be string or bytes")
Generating a JWT Encrypted with HS256
The following is the code to generate a JWT encrypted with HS256 using the above b64url
function:
# Enter Your Infomation Here ...
header = b64url('{"alg":"HS256","typ":"JWT"}')
payload = b64url('{"sub":"1234567890","name":"John Doe","iat":1516239022}')
secret = 'happynewyear'.encode('utf-8')
# ###
sig = b64url(hmac.new(
secret, (header + '.' + payload).encode('utf-8'), digestmod=sha256
).digest())
jwt = header + '.' + payload + '.' + sig
print(jwt)
Integrating JWT in FastAPI
Installing Dependencies
Before you start, you need to install fastapi
and uvicorn
. You can use the following command to install them:
pip install fastapi uvicorn
Implementation Steps
1. Creating a FastAPI Application
from fastapi import FastAPI, HTTPException, Depends
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import hmac
import base64
from hashlib import sha256
app = FastAPI()
# Define the b64url function
def b64url(str1):
if type(str1) == str:
return str(base64.b64encode(str1.encode('utf-8')), encoding="utf-8").strip('=').replace('+', '-').replace('/', '_')
elif type(str1) == bytes:
return str(base64.b64encode(str1), encoding="utf-8").strip('=').replace('+', '-').replace('/', '_')
else:
raise TypeError("The type of given argument must be string or bytes")
# Secret key
SECRET_KEY = 'happynewyear'.encode('utf-8')
# Function to generate JWT
def generate_jwt():
header = b64url('{"alg":"HS256","typ":"JWT"}')
payload = b64url('{"sub":"1234567890","name":"John Doe","iat":1516239022}')
sig = b64url(hmac.new(
SECRET_KEY, (header + '.' + payload).encode('utf-8'), digestmod=sha256
).digest())
return header + '.' + payload + '.' + sig
# Function to verify JWT
def verify_jwt(token: str):
parts = token.split('.')
if len(parts) != 3:
return False
header, payload, received_sig = parts
new_sig = b64url(hmac.new(
SECRET_KEY, (header + '.' + payload).encode('utf-8'), digestmod=sha256
).digest())
return new_sig == received_sig
# Define the JWT verification dependency
class JWTBearer(HTTPBearer):
def __init__(self, auto_error: bool = True):
super(JWTBearer, self).__init__(auto_error=auto_error)
async def __call__(self, request):
credentials: HTTPAuthorizationCredentials = await super(JWTBearer, self).__call__(request)
if credentials:
if not credentials.scheme == "Bearer":
raise HTTPException(status_code=401, detail="Invalid authentication scheme.")
if not verify_jwt(credentials.credentials):
raise HTTPException(status_code=401, detail="Invalid or expired token.")
return credentials.credentials
else:
raise HTTPException(status_code=401, detail="Invalid authorization code.")
2. Creating a Login Interface
# Simulated login interface
@app.post("/login")
def login():
token = generate_jwt()
return {"access_token": token, "token_type": "bearer"}
3. Creating a Protected Interface
# Protected interface
@app.get("/protected", dependencies=[Depends(JWTBearer())])
def protected_route():
return {"message": "This is a protected route."}
Running the Application
Save the above code as main.py
, and then run the following command in the terminal to start the application:
uvicorn main:app --reload
Testing the Interfaces
-
Login Interface: Use tools like
curl
or Postman to send a POST request tohttp://localhost:8000/login
, and it will return a JWT.
curl -X POST http://localhost:8000/login
-
Protected Interface: Use the returned JWT to send a GET request to
http://localhost:8000/protected
, and addAuthorization: Bearer <your_token>
to the request header.
curl -X GET http://localhost:8000/protected -H "Authorization: Bearer <your_token>"
Conclusion
Through the above steps, you have learned how to use JWT for authentication in FastAPI. JWT provides a secure and convenient way to manage user identities, making authentication between distributed systems more efficient. In practical applications, you can adjust the generation and verification logic of JWT according to your needs, such as adding an expiration time, customizing claims, etc.
Leapcell: The Best of Serverless Web Hosting
Finally, I would like to recommend a platform that is most suitable for deploying Python services: Leapcell
🚀 Build with Your Favorite Language
Develop effortlessly in JavaScript, Python, Go, or Rust.
🌍 Deploy Unlimited Projects for Free
Only pay for what you use—no requests, no charges.
⚡ Pay-as-You-Go, No Hidden Costs
No idle fees, just seamless scalability.
🔹 Follow us on Twitter: @LeapcellHQ
Top comments (0)