7dcc7dc0e1
This adds nginx dual-path routing, forwarded proxy headers, Uvicorn proxy-headers, production security settings, and deployment docs for https://sinbad2.ujaen.es/generadorexamenesllm/.
31 lines
1.3 KiB
Python
31 lines
1.3 KiB
Python
from fastapi import Request, Response
|
|
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
|
|
|
|
from app.core.config import Settings
|
|
|
|
|
|
class SecurityHeadersMiddleware(BaseHTTPMiddleware):
|
|
"""Cabeceras de seguridad; HSTS en producción o cuando el proxy indica HTTPS."""
|
|
|
|
def __init__(self, app: object, settings: Settings) -> None:
|
|
super().__init__(app)
|
|
self._settings = settings
|
|
|
|
async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response:
|
|
response = await call_next(request)
|
|
|
|
response.headers.setdefault("X-Content-Type-Options", "nosniff")
|
|
response.headers.setdefault("X-Frame-Options", "SAMEORIGIN")
|
|
response.headers.setdefault("Referrer-Policy", "strict-origin-when-cross-origin")
|
|
|
|
forwarded_proto = request.headers.get("x-forwarded-proto", request.url.scheme)
|
|
is_https = forwarded_proto == "https" or request.url.scheme == "https"
|
|
|
|
if is_https or self._settings.is_production:
|
|
hsts = f"max-age={self._settings.security_hsts_seconds}"
|
|
if self._settings.is_production:
|
|
hsts += "; includeSubDomains"
|
|
response.headers.setdefault("Strict-Transport-Security", hsts)
|
|
|
|
return response
|