DIY JWT Authentication in FastAPI Using Only Python
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 string s2. If there are equal signs at the end of s2, remove all equal signs at the end. If there are plus signs (+) in s2, replace all plus signs with minus signs (-). If there are slashes (/) in s2, 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 == "

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
to the request header.
curl -X GET http://localhost:8000/protected -H "Authorization: Bearer "
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