CoolFace
Apppublic

ashnaali22/phase-3-h2

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
dependencies.py93 linesDownload Raw Back to api
1from sqlalchemy.orm import Session
2from fastapi import Depends, HTTPException, Cookie, Header, status
3from typing import Optional
4from jose import JWTError
5from backend.database.connection import SessionLocal
6from backend.utils.jwt import decode_token
7
8
9def get_db() -> Session:
10    db = SessionLocal()
11    try:
12        yield db
13    finally:
14        db.close()
15
16
17def get_current_user_id(
18    auth_token: Optional[str] = Cookie(None),
19    authorization: Optional[str] = Header(None)
20) -> str:
21    """
22    Extract user_id from JWT token (Cookie OR Authorization header).
23
24    Supports both authentication methods for cross-domain compatibility:
25    1. Cookie: auth_token (same-site requests)
26    2. Authorization header: Bearer token (cross-site requests)
27
28    Args:
29        auth_token: JWT token from Cookie header
30        authorization: Bearer token from Authorization header
31
32    Returns:
33        user_id: User UUID as string
34
35    Raises:
36        HTTPException 401: If token is missing, invalid, or expired
37
38    Cache Behavior:
39        - Uses JWT caching from decode_token (5-minute TTL)
40        - Cache hit: <5ms response time
41        - Cache miss: ~40ms for JWT validation
42    """
43    import logging
44    logger = logging.getLogger(__name__)
45
46    # Debug logging
47    logger.info(f"[AUTH] Cookie token present: {bool(auth_token)}")
48    logger.info(f"[AUTH] Authorization header present: {bool(authorization)}")
49    if authorization:
50        logger.info(f"[AUTH] Authorization header value: {authorization[:30]}...")
51
52    # Try Authorization header first (for cross-domain requests)
53    token = None
54    if authorization and authorization.startswith("Bearer "):
55        token = authorization.replace("Bearer ", "")
56        logger.info(f"[AUTH] Extracted token from Authorization header: {token[:20]}...")
57    # Fall back to cookie (for same-site requests)
58    elif auth_token:
59        token = auth_token
60        logger.info(f"[AUTH] Using token from cookie: {token[:20]}...")
61
62    if not token:
63        logger.error("[AUTH] No token found in either Authorization header or cookie!")
64        raise HTTPException(
65            status_code=status.HTTP_401_UNAUTHORIZED,
66            detail="Authentication required. Please login to access this resource."
67        )
68
69    try:
70        # decode_token already implements caching with 5-minute TTL
71        # It will raise JWTError if token is invalid, expired, or malformed
72        payload = decode_token(token, use_cache=True)
73        user_id = payload.get("sub")
74
75        if not user_id:
76            raise HTTPException(
77                status_code=status.HTTP_401_UNAUTHORIZED,
78                detail="Invalid token: missing user identifier"
79            )
80
81        return user_id
82
83    except JWTError as e:
84        raise HTTPException(
85            status_code=status.HTTP_401_UNAUTHORIZED,
86            detail=f"Invalid or expired token: {str(e)}"
87        )
88    except ValueError as e:
89        raise HTTPException(
90            status_code=status.HTTP_401_UNAUTHORIZED,
91            detail=f"Token validation failed: {str(e)}"
92        )
93