How to Write Middleware using FastAPI
For one of my project, I needed to host an API service on the RapidAPI platform.
In order to make sure that all the requests to the application are routed via
RapidAPI I needed to check special header sent by RapidAPI.
RapidAPI forwards each valid request to the configured server, but injects
additional header X-RapidAPI-Proxy-Secret
. While a hacker may also send the
same header, the value of this header will be only known to RapidAPI platform
and your app.
I deployed the server on heroku, and defined an environment variable
PROXY_SECRET
which I check against the one sent with the request.
Sometimes I need to test the server directly, in which case I simply do not set
this variable (like on my local machine) and this check is bypassed.
Code
import os
from starlette.requests import Request
from starlette.responses import PlainTextResponse
app = FastAPI()
@app.middleware("http")
async def check_rapidAPI_proxy_header(request: Request, call_next):
# Check if server knows about valid "secret"
secret_header = os.environ.get("PROXY_SECRET", None)
if secret_header:
headers = request.headers
# If the header is missing, or does not match expected value
# Reject the request altogether
if (
"X-RapidAPI-Proxy-Secret" not in headers
or headers["X-RapidAPI-Proxy-Secret"] != secret_header
):
return PlainTextResponse(
"Direct access to the API not allowed", status_code=403
)
response = await call_next(request)
return response
Resources
- Uvcorn's ProxyMiddleWare - This is related but was not directly useful for me.
- FastAPI middleware documentation
- RapidAPI Proxy Secret
Published originally on my blog