# backend/auth/jwt.py import requests from jose import jwt from jose.exceptions import JWTError from fastapi import Depends, HTTPException, status from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from typing import Dict SUPABASE_PROJECT_ID = "lcoretjgpauozmuoedus" # <-- Replace with your project ref SUPABASE_JWKS_URL = f"https://{SUPABASE_PROJECT_ID}.supabase.co/auth/v1/keys" # Fetch JWKs from Supabase jwks = requests.get(SUPABASE_JWKS_URL).json() # Define FastAPI's bearer auth scheme auth_scheme = HTTPBearer() # Decode + verify JWT token def verify_jwt_token(token: str) -> Dict: try: header = jwt.get_unverified_header(token) kid = header["kid"] key = next((k for k in jwks["keys"] if k["kid"] == kid), None) if key is None: raise HTTPException(status_code=403, detail="Invalid Supabase JWT: No matching key") payload = jwt.decode(token, key, algorithms=["RS256"], options={"verify_aud": False}) return payload except JWTError as e: raise HTTPException(status_code=403, detail=f"Invalid Supabase JWT: {str(e)}") # Dependency for protected endpoints def get_current_user( credentials: HTTPAuthorizationCredentials = Depends(auth_scheme) ) -> Dict: token = credentials.credentials return verify_jwt_token(token)