eheguy commited on
Commit
b3dcf09
·
1 Parent(s): 8495baf

Secure backend JWT verification using Supabase JWKS signature validation

Browse files
Files changed (2) hide show
  1. main.py +16 -4
  2. 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
- options={"verify_signature": False}
 
 
 
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