morphos / backend /app /security /authz.py
Jose Salazar
A帽adir el stack nuevo: Vite/TypeScript + FastAPI
70e641d
Raw
History Blame Contribute Delete
1.53 kB
"""Dependencias de autorizaci贸n y CSRF para FastAPI.
Cierra el agujero cr铆tico de la versi贸n PHP: /api/interpret y /api/papers estaban
abiertos. Aqu铆 requieren sesi贸n v谩lida. Las peticiones mutantes exigen doble-token CSRF.
"""
from __future__ import annotations
import hmac
from fastapi import Cookie, Header, HTTPException, Request, status
from .session import CABECERA_CSRF, COOKIE_CSRF, COOKIE_SESION, leer_sesion
def usuario_actual(request: Request) -> dict:
"""Devuelve la sesi贸n o 401. Usar como dependencia en rutas protegidas."""
token = request.cookies.get(COOKIE_SESION)
sesion = leer_sesion(token)
if not sesion or not sesion.get("email"):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="No autenticado.")
return sesion
def verificar_csrf(
request: Request,
x_csrf_token: str | None = Header(default=None, alias=CABECERA_CSRF),
morphos_csrf: str | None = Cookie(default=None, alias=COOKIE_CSRF),
) -> None:
"""Double-submit cookie: la cabecera debe coincidir con la cookie CSRF."""
if request.method in ("GET", "HEAD", "OPTIONS"):
return
# Comparaci贸n en tiempo constante: el token es un secreto de sesi贸n, as铆 que se compara con
# compare_digest por costumbre defensiva (no con `!=`, que corta en el primer byte distinto).
if not x_csrf_token or not morphos_csrf or not hmac.compare_digest(x_csrf_token, morphos_csrf):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="CSRF inv谩lido.")