Saltar al contenido

CORS (Cross-Origin Resource Sharing)

CORS o "Cross-Origin Resource Sharing" se refiere a las situaciones en las que un frontend ejecutándose en un navegador tiene código JavaScript que se comunica con un backend, y el backend está en un "origen" diferente al del frontend.

Origen

Un origen es la combinación de protocolo (http, https), dominio (myapp.com, localhost, localhost.tiangolo.com) y puerto (80, 443, 8080).

Entonces, todos estos son orígenes diferentes:

  • http://localhost
  • https://localhost
  • http://localhost:8080

Incluso si están todos en localhost, usan diferentes protocolos o puertos, por lo que son "orígenes" diferentes.

Pasos

Digamos que tienes un frontend ejecutándose en tu navegador en http://localhost:8080, y su JavaScript intenta comunicarse con un backend ejecutándose en http://localhost (como no especificamos un puerto, el navegador asumirá el puerto por defecto 80).

Luego, el navegador enviará una petición HTTP OPTIONS al backend en el :80, y si el backend envía las cabeceras apropiadas autorizando la comunicación desde este origen diferente (http://localhost:8080), entonces el navegador en el :8080 permitirá que el JavaScript del frontend envíe su petición al backend en el :80.

Para lograr esto, el backend en el :80 debe tener una lista de "orígenes permitidos".

En este caso, la lista tendría que incluir http://localhost:8080 para que el frontend en el :8080 funcione correctamente.

Comodines

También es posible declarar la lista como "*" (un "comodín") para indicar que todos están permitidos.

Pero eso solo permitirá ciertos tipos de comunicación, excluyendo todo lo que involucre credenciales: Cookies, cabeceras de Authorization como las que se usan con Bearer Tokens, etc.

Por lo tanto, para que todo funcione correctamente, es mejor especificar explícitamente los orígenes permitidos.

Usar CORSMiddleware

Puedes configurarlo en tu aplicación FastAPI usando el CORSMiddleware.

  • Importa CORSMiddleware.
  • Crea una lista de orígenes permitidos (como strings).
  • Añádelo como un "middleware" a tu aplicación FastAPI.

También puedes especificar si tu backend permite:

  • Credenciales (cabeceras de Authorization, Cookies, etc).
  • Métodos HTTP específicos (POST, PUT) o todos ellos con el comodín "*".
  • Cabeceras HTTP específicas o todas ellas con el comodín "*".
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost.tiangolo.com",
    "https://localhost.tiangolo.com",
    "http://localhost",
    "http://localhost:8080",
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/")
async def main():
    return {"message": "Hello World"}

Los parámetros por defecto usados por la implementación de CORSMiddleware son restrictivos por defecto, por lo que necesitarás habilitar explícitamente orígenes, métodos o cabeceras particulares para que los navegadores puedan usarlos en un contexto Cross-Domain.

Los siguientes argumentos son soportados:

  • allow_origins - Una lista de orígenes que deberían tener permitido hacer peticiones cross-origin. Por ejemplo, ['https://example.org', 'https://www.example.org']. Puedes usar ['*'] para permitir cualquier origen.
  • allow_origin_regex - Un string de expresión regular para coincidir con orígenes que deberían tener permitido hacer peticiones cross-origin. Por ejemplo, 'https://.*\.example\.org'.
  • allow_methods - Una lista de métodos HTTP que deberían estar permitidos para peticiones cross-origin. Por defecto es ['GET']. Puedes usar ['*'] para permitir todos los métodos estándar.
  • allow_headers - Una lista de cabeceras de petición HTTP que deberían estar soportadas para peticiones cross-origin. Por defecto es []. Puedes usar ['*'] para permitir todas las cabeceras. Las cabeceras Accept, Accept-Language, Content-Language y Content-Type siempre están permitidas para peticiones CORS simples.
  • allow_credentials - Indica que las cookies deberían estar soportadas para peticiones cross-origin. Por defecto es False.

    Ninguno de allow_origins, allow_methods y allow_headers puede establecerse como ['*'] si allow_credentials está establecido como True. Todos deben ser especificados explícitamente.

  • expose_headers - Indica cualquier cabecera de respuesta que debería ser accesible para el navegador. Por defecto es [].

  • max_age - Establece un tiempo máximo en segundos para que los navegadores cacheen las respuestas CORS. Por defecto es 600.

El middleware responde a dos tipos particulares de petición HTTP...

Peticiones CORS preflight

Estas son cualquier petición OPTIONS con cabeceras Origin y Access-Control-Request-Method.

En este caso el middleware interceptará la petición entrante y responderá con las cabeceras CORS apropiadas, y con una respuesta 200 o 400 con fines informativos.

Peticiones simples

Cualquier petición con una cabecera Origin. En este caso el middleware pasará la petición de forma normal, pero incluirá las cabeceras CORS apropiadas en la respuesta.

Más información

Para más información sobre CORS, consulta la documentación de CORS de Mozilla.

Detalles Técnicos

También puedes usar from starlette.middleware.cors import CORSMiddleware.

FastAPI proporciona varios middlewares en fastapi.middleware solo como una conveniencia para ti, el desarrollador. Pero la mayoría de los middlewares disponibles vienen directamente de Starlette.