Introducción
Contenido
- 1 Introducción
- 2 Que es CORS
- 3 Configuración de CORS con Express
- 4 Habilitar todas las solicitudes CORS
- 5 Habilitar CORS para una sola ruta
- 6 Configurar CORS con opciones
- 7 Configuración de orígenes dinámicos de CORS mediante una función
- 8 Cargando lista de orígenes permitidos desde como fuente de datos
- 9 Conclusión
En este artículo, veremos qué es CORS, cómo puede configurar CORS con Express y cómo personalizar el middleware CORS según sus necesidades.
Que es CORS
CORS es la abreviatura de Intercambio de recursos entre orígenes. Es un mecanismo para permitir o restringir los recursos solicitados en un servidor web dependiendo de dónde se inició la solicitud HTTP.
Esta política se utiliza para proteger un determinado servidor web del acceso de otro sitio web o dominio. Por ejemplo, solo los dominios permitidos podrán acceder a los archivos alojados en un servidor, como una hoja de estilo, una imagen o un script.
Si está actualmente en http://example.com/page1
y te refieres a una imagen de http://image.com/myimage.jpg
no podrás recuperar esa imagen a menos que http://image.com
permite compartir orígenes cruzados con http://example.com
.
Hay un encabezado HTTP llamado origin
en cada solicitud HTTP. Define desde dónde se originó la solicitud de dominio. Podemos utilizar la información del encabezado para restringir o permitir recursos de nuestro servidor web para protegerlos.
Por defecto, las solicitudes de cualquier otro origen estarán restringidas por el navegador.
Por ejemplo, mientras aún se encuentra en la etapa de desarrollo, si está utilizando una biblioteca de interfaz como React, su aplicación de interfaz se servirá en http://localhost:3000
. Mientras tanto, su servidor Express puede estar ejecutándose en un puerto diferente, como http://localhost:2020
.
Debido a esto, deberá permitir CORS entre esos servidores.
Si ve este error común en la consola de su navegador. Las restricciones de CORS podrían ser el problema:
CORS es realmente útil cuando está ofreciendo una API pública y le gustaría controlar el acceso a ciertos recursos y cómo la gente los usa.
Además, si desea usar su propia API o archivos en una página web diferente, simplemente puede configurar CORS para permitir eso, mientras bloquea a otros.
Configuración de CORS con Express
Comencemos con un proyecto nuevo. Haremos un directorio para él, lo ingresaremos y ejecutaremos npm init
con la configuración predeterminada:
$ mkdir myapp
$ cd myapp
$ npm init -y
Luego instalemos los módulos requeridos. Estaremos usando express
y el cors
middleware:
$ npm i --save express
$ npm i --save cors
Entonces comencemos a crear una aplicación web rápida con dos rutas para demostrar cómo funciona CORS.
Te puede interesar:Escribir en archivos usando el comando cat en LinuxHaremos un archivo, llamado index.js
que actúa como un servidor web, con un par de controladores de solicitudes:
const express = require('express');
const cors = require('cors');
const app = express();
app.get("https://Pharos.sh.com/", (req, res) => {
res.json({
message: 'Hello World'
});
});
app.get('/:name', (req, res) => {
let name = req.params.name;
res.json({
message: `Hello ${name}`
});
});
app.listen(2020, () => {
console.log('server is listening on port 2020');
});
Ejecutemos la aplicación y el servidor:
$ node index.js
Ahora, si vas a http://localhost:2020/
– el servidor debe devolver un mensaje JSON:
{
"message": "Hello World"
}
Alternativamente, si vas a http://localhost:2020/something
debería ver:
{
"message": "Hello something"
}
Habilitar todas las solicitudes CORS
Si desea habilitar CORS para todas las solicitudes, simplemente puede usar el cors
middleware antes de configurar sus rutas:
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors())
......
Esto permitirá acceder a todas las rutas desde cualquier lugar de la web si eso es lo que necesita. Entonces, en nuestro ejemplo, ambas rutas serán accesibles para todos los dominios.
Por ejemplo, si nuestro servidor se ejecuta en http://www.example.com
y ofrece contenido como imágenes; permitimos otros dominios, como http://www.differentdomain.com
para referir el contenido de http://www.example.com
.
Así, una página web en http://www.differentdomain.com
puede usar nuestro dominio como fuente para una imagen:
<img src="https://www.example.com/img/cat.jpg">
Habilitar CORS para una sola ruta
Pero si necesita que una determinada ruta sea accesible y no otras rutas, puede configurar cors
en una ruta determinada como middleware en lugar de configurarlo para toda la aplicación:
app.get("https://Pharos.sh.com/", cors(), (req, res) => {
res.json({
message: 'Hello World'
});
});
Esto permitirá que una determinada ruta sea accesible por cualquier dominio. Entonces, en tu caso, solo el /
La ruta será accesible para todos los dominios. los /:name
La ruta solo será accesible para las solicitudes que se iniciaron en el mismo dominio que la API, que es http://localhost:2020
en nuestro caso.
Por ejemplo, si intenta enviar una solicitud de recuperación al /
ruta desde un origen diferente: tendrá éxito y obtendrá el Hello World
mensaje como respuesta:
fetch('http://localhost:2020/')
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error(err));
Debería ver que la respuesta del servidor se registró correctamente en la consola si ejecuta este código:
{
message: 'Hello World'
}
Pero si intenta acceder a cualquier otra ruta que no sea la ruta raíz, como http://localhost:2020/name
o http://localhost:2020/img/cat.png
esta solicitud será bloqueada por el navegador:
fetch('http://localhost:2020/name/janith')
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error(err));
Debería ver el siguiente error si intenta ejecutar este código en una aplicación web diferente:
Te puede interesar:El mito de la multitarea como desarrolladorConfigurar CORS con opciones
También puede usar las opciones de configuración con CORS para personalizar esto aún más. Puede usar la configuración para permitir el acceso a un solo dominio o subdominios, configurar métodos HTTP que estén permitidos, como GET
y POST
dependiendo de sus requerimientos.
Así es como puede permitir el acceso de un solo dominio usando las opciones de CORS:
var corsOptions = {
origin: 'http://localhost:8080',
optionsSuccessStatus: 200 // For legacy browser support
}
app.use(cors(corsOptions));
Si configura el nombre de dominio en el origen, el servidor permitirá CORS desde el dominio configurado. Entonces la API será accesible desde http://localhost:8080
en nuestro caso y bloqueado para otros dominios.
Si enviamos un GET
solicitud, acceder a cualquier ruta debería funcionar, ya que las opciones se aplican a nivel de aplicación, no a nivel de función.
Entonces, si ejecutamos el siguiente código y enviamos una solicitud desde http://localhost:8080
a http://localhost:2020
:
fetch('http://localhost:2020/')
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error(err));
// Or
fetch('http://localhost:2020/name/janith')
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error(err));
Se nos permite obtener la información de esa aplicación y dominio.
También puede configurar los métodos HTTP permitidos si lo desea:
Te puede interesar:Preparación para una entrevista de trabajo como programadorvar corsOptions = {
origin: 'http://localhost:8080',
optionsSuccessStatus: 200 // For legacy browser support
methods: "GET, PUT"
}
app.use(cors(corsOptions));
Si enviamos un POST
solicitud de http://localhost:8080
, será bloqueado por el navegador como solo GET
y PUT
son compatibles:
fetch('http://localhost:2020', {
method: 'POST',
body: JSON.stringify({name: "janith"}),
})
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error(err));
Para ver una lista completa de opciones de configuración, consulte la documentación oficial.
Configuración de orígenes dinámicos de CORS mediante una función
Si las configuraciones no satisfacen sus requisitos, puede crear su función para personalizar CORS.
Por ejemplo, supongamos que desea permitir el uso compartido de CORS para .jpg
archivos http://something.com
y http://example.com
:
const allowlist = ['http://something.com', 'http://example.com'];
const corsOptionsDelegate = (req, callback) => {
let corsOptions;
let isDomainAllowed = whitelist.indexOf(req.header('Origin')) !== -1;
let isExtensionAllowed = req.path.endsWith('.jpg');
if (isDomainAllowed && isExtensionAllowed) {
// Enable CORS for this request
corsOptions = { origin: true }
} else {
// Disable CORS for this request
corsOptions = { origin: false }
}
callback(null, corsOptions)
}
app.use(cors(corsOptionsDelegate));
La función de devolución de llamada aceptará dos parámetros. El primero es un error por donde pasamos null
y el segundo son opciones por donde pasamos { origin: false }
. El segundo parámetro podría ser muchas opciones que se construyen utilizando el request
objeto del controlador de solicitudes Express.
Entonces, una aplicación web alojada en http://something.com
o http://example.com
podría referir una imagen con .jpg
extensión desde el servidor como hemos configurado en nuestra función personalizada.
Entonces, el siguiente archivo adjunto de imagen será exitoso desde cualquiera de estos:
Te puede interesar:Uso de Sequelize.js y SQLite en una aplicación Express.js<img src="https://yourdomain.com/img/cat.jpg">
Pero se bloqueará el siguiente archivo adjunto:
<img src="https://yourdomain.com/img/cat.png">
Cargando lista de orígenes permitidos desde como fuente de datos
También puede usar una lista de dominios permitidos de una base de datos o usar cualquier fuente de datos de respaldo para permitir CORS:
var corsOptions = {
origin: function (origin, callback) {
// Loading a list of allowed origins from the database
// Ex.. origins = ['http://example.com', 'http//something.com']
database.loadOrigins((error, origins) => {
callback(error, origins);
});
}
}
app.use(cors(corsOptions));
Conclusión
En este artículo, hemos cubierto qué es CORS y cómo puede configurarlo con Express. Luego, configuramos CORS para todas las solicitudes, para solicitudes específicas, agregamos opciones y restricciones, así como también definimos una función personalizada para la configuración dinámica de CORS.