Data-wiz-project / api /app /firebase_auth.py
github-actions
Deploy API from a602880
dc3810a
Raw History Blame Contribute Delete
1.56 kB
"""Verify Firebase ID tokens sent as `Authorization: Bearer <token>`.
The Firebase web config is public by design. What protects us is verifying every token's
signature, audience (our project id) and issuer against Google's published keys.
Tests replace `verify` with a stub.
"""
from __future__ import annotations
from fastapi import Header, HTTPException
from google.auth.transport import requests as g_requests
from google.oauth2 import id_token
from .config import get_settings
_request = g_requests.Request()
def verify(token: str) -> dict:
"""Return the token claims, or raise ValueError."""
return id_token.verify_firebase_token(token, _request, audience=get_settings().firebase_project_id)
def claims_from_header(authorization: str | None) -> dict | None:
if not authorization or not authorization.lower().startswith("bearer "):
return None
token = authorization[7:].strip()
try:
c = verify(token)
except Exception: # noqa: BLE001 - any failure means "not authenticated"
raise HTTPException(401, "Sign-in expired or invalid. Please sign in again.")
return {"uid": c["sub"], "email": (c.get("email") or "").lower(), "email_verified": bool(c.get("email_verified")),
"name": (c.get("name") or "").strip(), "provider": (c.get("firebase") or {}).get("sign_in_provider", "")}
def current_user(authorization: str | None = Header(default=None)) -> dict:
c = claims_from_header(authorization)
if not c:
raise HTTPException(401, "Sign in to continue.")
return c