File size: 1,272 Bytes
a5ea774
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import os
import hmac

from fastapi import Request
from fastapi.responses import JSONResponse
from starlette.middleware.base import BaseHTTPMiddleware

PUBLIC_ROUTES = {"/", "/health", "/docs", "/openapi.json", "/redoc"}


class APIKeyMiddleware(BaseHTTPMiddleware):
    def __init__(self, app):
        super().__init__(app)
        self.secret_key = os.getenv("API_SECRET_KEY", "")

    async def dispatch(self, request: Request, call_next):
        if request.url.path.rstrip("/") in PUBLIC_ROUTES:
            return await call_next(request)

        if not self.secret_key:
            return JSONResponse(
                status_code=503,
                content={"detail": "Service misconfigured: API_SECRET_KEY is not set."},
            )

        provided_key = request.headers.get("X-API-Key", "")

        if not provided_key:
            return JSONResponse(
                status_code=401,
                content={"detail": "Missing API key. Pass it as the 'X-API-Key' header."},
            )

        if not hmac.compare_digest(provided_key.encode(), self.secret_key.encode()):
            return JSONResponse(
                status_code=403,
                content={"detail": "Invalid API key."},
            )

        return await call_next(request)