Manejo de CORS con Node.js

    Introducci贸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.

    Haremos 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:

    Configurar 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:

    var 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:

    <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.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *