digitalbillboard / core /dependencies.py
Hammad712's picture
Deploying Axiom Backend to HF Spaces
f3f21dd
from fastapi import Request, HTTPException, status
from supabase import create_client, Client, ClientOptions
from core.config import settings
from core.logger import logger
async def get_current_user_client(request: Request) -> Client:
"""
Verifies the token from the secure cookie (or Auth header)
and returns a Supabase client scoped to this specific user.
"""
# 1. Look for the token in the secure HTTPOnly cookie
token = request.cookies.get("access_token")
# 2. Fallback: If no cookie, check the Authorization header
if not token:
auth_header = request.headers.get("Authorization")
if auth_header and auth_header.startswith("Bearer "):
token = auth_header.split(" ")[1]
# If still no token, block the request immediately
if not token:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Not authenticated. Missing cookie or token."
)
try:
# 3. Create the client with specific user headers
custom_options = ClientOptions(headers={"Authorization": f"Bearer {token}"})
user_client: Client = create_client(
settings.SUPABASE_URL,
settings.SUPABASE_KEY,
options=custom_options
)
# 4. CRITICAL FIX: Synchronize the SDK's internal auth state.
# This prevents 'NoneType' errors when calling user_client.auth later.
user_client.auth.set_session(token, "refresh_token_not_needed")
# 5. Verify the token is still valid with Supabase
user_response = user_client.auth.get_user(token)
if not user_response or not user_response.user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid or expired token"
)
# 6. Attach the user object for easy access in our services
# This is the 'Axiom' Protocol: we pull this in our routes to avoid re-fetching.
user_client.current_user = user_response.user
return user_client
except Exception as e:
logger.error(f"Auth Dependency Failure: {str(e)}")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=f"Could not validate credentials: {str(e)}"
)