Spaces:
Running
Running
eheguy commited on
Commit ·
b3dcf09
1
Parent(s): 8495baf
Secure backend JWT verification using Supabase JWKS signature validation
Browse files- main.py +16 -4
- requirements.txt +1 -0
main.py
CHANGED
|
@@ -6,6 +6,7 @@ from pydantic import BaseModel
|
|
| 6 |
from dotenv import load_dotenv
|
| 7 |
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
| 8 |
import jwt
|
|
|
|
| 9 |
import base64
|
| 10 |
from slowapi import Limiter, _rate_limit_exceeded_handler
|
| 11 |
from slowapi.util import get_remote_address
|
|
@@ -38,21 +39,32 @@ RAZORPAY_PRO_PLAN_ID = os.getenv("RAZORPAY_PRO_PLAN_ID")
|
|
| 38 |
razorpay_client = razorpay.Client(auth=(RAZORPAY_KEY_ID or "", RAZORPAY_KEY_SECRET or ""))
|
| 39 |
|
| 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
security = HTTPBearer()
|
| 42 |
|
| 43 |
def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
|
| 44 |
token = credentials.credentials
|
| 45 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
payload = jwt.decode(
|
| 47 |
token,
|
| 48 |
-
|
|
|
|
|
|
|
|
|
|
| 49 |
)
|
| 50 |
user_id = payload.get("sub")
|
| 51 |
if not user_id:
|
| 52 |
-
raise HTTPException(status_code=401, detail="Invalid token")
|
| 53 |
return user_id
|
| 54 |
-
except Exception:
|
| 55 |
-
raise HTTPException(status_code=401, detail="Invalid or expired token")
|
| 56 |
|
| 57 |
INJECTION_PATTERNS = [
|
| 58 |
r"ignore\s*(all\s*)?(previous|prior|above)\s*(instructions?|prompts?|context)",
|
|
|
|
| 6 |
from dotenv import load_dotenv
|
| 7 |
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
| 8 |
import jwt
|
| 9 |
+
from jwt import PyJWKClient
|
| 10 |
import base64
|
| 11 |
from slowapi import Limiter, _rate_limit_exceeded_handler
|
| 12 |
from slowapi.util import get_remote_address
|
|
|
|
| 39 |
razorpay_client = razorpay.Client(auth=(RAZORPAY_KEY_ID or "", RAZORPAY_KEY_SECRET or ""))
|
| 40 |
|
| 41 |
|
| 42 |
+
SUPABASE_URL = os.getenv("SUPABASE_URL")
|
| 43 |
+
JWKS_URL = f"{SUPABASE_URL}/auth/v1/.well-known/jwks.json" if SUPABASE_URL else ""
|
| 44 |
+
jwks_client = PyJWKClient(JWKS_URL) if JWKS_URL else None
|
| 45 |
+
|
| 46 |
security = HTTPBearer()
|
| 47 |
|
| 48 |
def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
|
| 49 |
token = credentials.credentials
|
| 50 |
try:
|
| 51 |
+
if not jwks_client:
|
| 52 |
+
raise ValueError("SUPABASE_URL is not set.")
|
| 53 |
+
|
| 54 |
+
signing_key = jwks_client.get_signing_key_from_jwt(token)
|
| 55 |
payload = jwt.decode(
|
| 56 |
token,
|
| 57 |
+
signing_key.key,
|
| 58 |
+
algorithms=["HS256", "RS256"],
|
| 59 |
+
audience="authenticated",
|
| 60 |
+
options={"verify_aud": True}
|
| 61 |
)
|
| 62 |
user_id = payload.get("sub")
|
| 63 |
if not user_id:
|
| 64 |
+
raise HTTPException(status_code=401, detail="Invalid token claims")
|
| 65 |
return user_id
|
| 66 |
+
except Exception as e:
|
| 67 |
+
raise HTTPException(status_code=401, detail=f"Invalid or expired token: {str(e)}")
|
| 68 |
|
| 69 |
INJECTION_PATTERNS = [
|
| 70 |
r"ignore\s*(all\s*)?(previous|prior|above)\s*(instructions?|prompts?|context)",
|
requirements.txt
CHANGED
|
@@ -5,4 +5,5 @@ groq
|
|
| 5 |
supabase
|
| 6 |
razorpay>=1.3.0
|
| 7 |
PyJWT
|
|
|
|
| 8 |
slowapi>=0.1.9
|
|
|
|
| 5 |
supabase
|
| 6 |
razorpay>=1.3.0
|
| 7 |
PyJWT
|
| 8 |
+
cryptography
|
| 9 |
slowapi>=0.1.9
|