middleware cors
CORS es un middleware de Node.js para Express/Connect que establece los encabezados de respuesta CORS. Estos encabezados indican a los navegadores qué orígenes pueden leer las respuestas de tu servidor.
Nota
Cómo funciona CORS: Este paquete establece encabezados de respuesta, no bloquea peticiones. CORS es aplicado por los navegadores: revisan los encabezados y deciden si JavaScript puede leer la respuesta. Los clientes que no son navegadores (curl, Postman, otros servidores) ignoran CORS por completo. Consulta la guía de CORS de MDN para más detalles.
Instalación
Este es un módulo de Node.js disponible a través del
registro npm. La instalación se hace usando el
comando npm install:
npm install corsyarn add corspnpm add corsbun add corsUso
Uso simple (Habilitar todas las peticiones CORS)
var express = require('express');var cors = require('cors');var app = express();
// Adds headers: Access-Control-Allow-Origin: *app.use(cors());
app.get('/products/:id', function (req, res, next) { res.json({ msg: 'Hello' });});
app.listen(80, function () { console.log('web server listening on port 80');});Habilitar CORS para una sola ruta
var express = require('express');var cors = require('cors');var app = express();
// Adds headers: Access-Control-Allow-Origin: *app.get('/products/:id', cors(), function (req, res, next) { res.json({ msg: 'Hello' });});
app.listen(80, function () { console.log('web server listening on port 80');});Configurar CORS
Consulta las opciones de configuración para más detalles.
var express = require('express');var cors = require('cors');var app = express();
var corsOptions = { origin: 'http://example.com', optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204};
// Adds headers: Access-Control-Allow-Origin: http://example.com, Vary: Originapp.get('/products/:id', cors(corsOptions), function (req, res, next) { res.json({ msg: 'Hello' });});
app.listen(80, function () { console.log('web server listening on port 80');});Configurar CORS con origen dinámico
Este módulo soporta la validación del origen dinámicamente usando una función
proporcionada a la opción origin. A esta función se le pasará una cadena que es
el origen (o undefined si la petición no tiene origen), y un callback con la firma
callback(error, origin).
El argumento origin del callback puede ser cualquier valor permitido para la
opción origin del middleware, excepto una función. Consulta la sección de
opciones de configuración para más información sobre todos
los tipos de valores posibles.
Esta función está diseñada para permitir la carga dinámica de los orígenes permitidos desde una fuente de datos de respaldo, como una base de datos.
var express = require('express');var cors = require('cors');var app = express();
var corsOptions = { origin: function (origin, callback) { // db.loadOrigins is an example call to load // a list of origins from a backing database db.loadOrigins(function (error, origins) { callback(error, origins); }); },};
// Adds headers: Access-Control-Allow-Origin: <matched origin>, Vary: Originapp.get('/products/:id', cors(corsOptions), function (req, res, next) { res.json({ msg: 'Hello' });});
app.listen(80, function () { console.log('web server listening on port 80');});Habilitar pre-flight de CORS
Ciertas peticiones CORS se consideran ‘complejas’ y requieren una petición inicial
OPTIONS (llamada “petición pre-flight”). Un ejemplo de una petición CORS
‘compleja’ es una que usa un verbo HTTP distinto a GET/HEAD/POST (como DELETE)
o que usa encabezados personalizados. Para habilitar el pre-flight, debes añadir un
nuevo manejador OPTIONS para la ruta que quieres soportar:
var express = require('express');var cors = require('cors');var app = express();
app.options('/products/:id', cors()); // preflight for DELETEapp.delete('/products/:id', cors(), function (req, res, next) { res.json({ msg: 'Hello' });});
app.listen(80, function () { console.log('web server listening on port 80');});También puedes habilitar el pre-flight de forma global así:
app.options('*', cors()); // include before other routesNOTA: Cuando se usa este middleware como middleware a nivel de aplicación (por
ejemplo, app.use(cors())), las peticiones pre-flight ya se manejan para todas
las rutas.
Personalizar la configuración CORS dinámicamente por petición
Para APIs que requieren diferentes configuraciones CORS para rutas o peticiones específicas, puedes generar dinámicamente las opciones CORS basándote en la petición entrante. El middleware cors te permite lograr esto pasando una función en lugar de opciones estáticas. Esta función se llama para cada petición entrante y debe usar el patrón callback para devolver las opciones CORS apropiadas.
La función acepta:
-
req:- El objeto de petición entrante.
-
callback(error, corsOptions):- Una función usada para devolver las opciones CORS calculadas.
- Arguments:
error: Pasanullsi no hay error, o un objeto de error para indicar un fallo.corsOptions: Un objeto que especifica la política CORS para la petición actual.
Aquí hay un ejemplo que maneja tanto rutas públicas como rutas restringidas sensibles a credenciales:
var dynamicCorsOptions = function (req, callback) { var corsOptions; if (req.path.startsWith('/auth/connect/')) { // Access-Control-Allow-Origin: http://mydomain.com, Access-Control-Allow-Credentials: true, Vary: Origin corsOptions = { origin: 'http://mydomain.com', credentials: true, }; } else { // Access-Control-Allow-Origin: * corsOptions = { origin: '*' }; } callback(null, corsOptions);};
app.use(cors(dynamicCorsOptions));
app.get('/auth/connect/twitter', function (req, res) { res.send('Hello');});
app.get('/public', function (req, res) { res.send('Hello');});
app.listen(80, function () { console.log('web server listening on port 80');});Opciones de configuración
origin: Configures the Access-Control-Allow-Origin CORS header. Possible values:Boolean- estableceorigincomotruepara reflejar el origen de la petición, definido porreq.header('Origin'), o establécelo comofalsepara deshabilitar CORS.String- setoriginto a specific origin. For example, if you set it to"http://example.com"solo se permitirán las peticiones de “http://example.com”."*"para permitir todos los dominios.
RegExp- estableceorigincomo un patrón de expresión regular que se usará para probar el origen de la petición. Si coincide, se reflejará el origen de la petición. Por ejemplo, el patrón/example\.com$/reflejará cualquier petición que venga de un origen que termine con “example.com”.Array- estableceorigincomo un array de orígenes válidos. Cada origen puede ser unStringo unRegExp. Por ejemplo,["http://example1.com", /\.example2\.com$/]aceptará cualquier petición de “http://example1.com” o de un subdominio de “example2.com”.Function- estableceorigincomo una función que implementa alguna lógica personalizada. La función toma el origen de la petición como primer parámetro y un callback (llamado comocallback(err, origin), dondeorigines un valor que no es función de la opciónorigin) como segundo.
methods: Configura el encabezado CORS Access-Control-Allow-Methods. Espera una cadena delimitada por comas (ej: ‘GET,PUT,POST’) o un array (ej:['GET', 'PUT', 'POST']).allowedHeaders: Configura el encabezado CORS Access-Control-Allow-Headers. Espera una cadena delimitada por comas (ej: ‘Content-Type,Authorization’) o un array (ej:['Content-Type', 'Authorization']). Si no se especifica, por defecto refleja los encabezados especificados en el encabezado Access-Control-Request-Headers de la petición.exposedHeaders: Configura el encabezado CORS Access-Control-Expose-Headers. Espera una cadena delimitada por comas (ej: ‘Content-Range,X-Content-Range’) o un array (ej:['Content-Range', 'X-Content-Range']). Si no se especifica, no se exponen encabezados personalizados.credentials: Configura el encabezado CORS Access-Control-Allow-Credentials. Establece comotruepara pasar el encabezado, de lo contrario se omite.maxAge: Configura el encabezado CORS Access-Control-Max-Age. Establece como un entero para pasar el encabezado, de lo contrario se omite.preflightContinue: Pasa la respuesta preflight de CORS al siguiente manejador.optionsSuccessStatus: Proporciona un código de estado a usar para peticionesOPTIONSexitosas, ya que algunos navegadores antiguos (IE11, varios SmartTVs) tienen problemas con204.
La configuración por defecto es equivalente a:
{ "origin": "*", "methods": "GET,HEAD,PUT,PATCH,POST,DELETE", "preflightContinue": false, "optionsSuccessStatus": 204}Conceptos erróneos comunes
”CORS bloquea las peticiones de orígenes no permitidos”
No. Tu servidor recibe y procesa cada petición. Los encabezados CORS le indican al navegador si JavaScript puede leer la respuesta, no si la petición está permitida.
”CORS protege mi API de accesos no autorizados”
No. CORS no es control de acceso. Cualquier cliente HTTP (curl, Postman, otro servidor) puede llamar a tu API independientemente de la configuración CORS. Usa autenticación y autorización para proteger tu API.
”Establecer origin: 'http://example.com' significa que solo ese dominio puede acceder a mi servidor”
No. Significa que los navegadores solo permitirán que JavaScript de ese origen lea las respuestas. El servidor sigue respondiendo a todas las peticiones.