Cómo cargar y entregar datos usando Amazon CloudFront y Amazon S3 en Node.js
S3 — La mayoría de las aplicaciones actuales sirven a usuarios de todo el mundo y necesitan una forma de entregar su contenido rápidamente. El contenido puede ser imágenes, videos, PDF, etc. La red de entrega de contenido (CDN) es una red de servidores que se distribuyen geográficamente con la intención de ofrecer contenido a los usuarios lo más rápido posible.
Amazon CloudFront es un servicio de red de entrega de contenido que puede entregar contenido de forma rápida y segura. En este artículo, describiré cómo cargar archivos en el bucket de S3 y entregar esos archivos a través de CloudFront en Node.js. CloudFront utilizará S3 como origen en este artículo.
Prerrequisitos
Cree un depósito en S3 y cree una distribución de CloudFront en AWS. No entraré en detalles sobre la creación de un bucket de S3 y la distribución de CloudFront en este artículo. Navegue a IAM y vaya a “Credenciales de seguridad” en usuario. Cree una clave de acceso y descargue el archivo CSV en caso de que aún no tenga una. Necesitaremos esta clave de acceso más tarde.
Luego, haga clic en ‘My Security Credentials’ (Mis credenciales de seguridad) debajo de su cuenta.
En Pares de claves de CloudFront, cree un par de claves y descargue la clave privada y anote su ID de clave de acceso. Los necesitaremos más tarde para la integración.
Creando la aplicación Node.js
Creemos un servidor rápido Node.js simple y agreguemos dos puntos finales de API REST para la carga y descarga de archivos. Aquí está la estructura del proyecto de muestra.
Estoy usando módulos mecanografiados y ts-node-dev npm en este proyecto de muestra. Por lo tanto, tengo tsconfig.json en el proyecto.
Aquí está el archivo app.ts completo. El archivo contiene la lógica para inicializar el servidor express y los puntos finales REST. También estoy usando el módulo multer npm para manejar la carga de archivos de varias partes.
import express from 'express'; import * as fileCtrl from './fileController'; import multer from 'multer'; import crypto from 'crypto'; import path from 'path'; const app = express(); const port = 3000; app.listen(port, () => { console.log('Server listening on port %s.', port); }); //Multer module for handling multi part file upload. var storage = multer.diskStorage({ destination: './files', filename: function (req, file, cb) { crypto.pseudoRandomBytes(16, function (err, raw) { if (err) return cb(err) cb(null, raw.toString('hex') + path.extname(file.originalname)) }) } }) app.use(multer({ storage: storage }).single('file')); app.get('/api/download', asyncHandler(fileCtrl.download)); app.post('/api/upload', asyncHandler(fileCtrl.upload)); export function asyncHandler(handler) { return function (req, res, next) { if (!handler) { next(new Error(`Invalid handler ${handler}, it must be a function.`)); } else { handler(req, res, next).catch(next); } }; }
Carga de archivos en Amazon S3 Bucket
Veamos cómo cargar archivos en el bucket de S3. Necesitaremos instalar el módulo de nodo aws-sdk para acceder a los depósitos de S3 desde la aplicación Node.js.
Una vez que lo hemos instalado, el controlador para el punto final de carga se define de la siguiente manera:
export async function upload(req, res) { let response = await uploadFile(req.file.originalname, req.file.path); res.send(response); res.end(); }
En fileComponent.ts, necesitamos importar el módulo aws-sdk de la siguiente manera.
import awsSDK from 'aws-sdk';
Al comienzo de este artículo, descargamos un archivo CSV que contenía la identificación de la clave de acceso y la clave de acceso secreta. Los usaremos para subir archivos al bucket de S3. Usando el módulo aws-sdk, necesitamos configurar la identificación de la clave de acceso y la clave de acceso secreta de la siguiente manera:
export function uploadFile(filename, fileDirectoryPath) { awsSDK.config.update({ accessKeyId: process.env.S3_ACCESS_KEY_ID, secretAccessKey: process.env.S3_SECRET_ACCESS_KEY }); const s3 = new awsSDK.S3(); return new Promise(function (resolve, reject) { fs.readFile(fileDirectoryPath.toString(), function (err, data) { if (err) { reject(err); } s3.putObject({ Bucket: '' + process.env.S3_BUCKET_NAME, Key: filename, Body: data, ACL: 'public-read' }, function (err, data) { if (err) reject(err); resolve("succesfully uploaded"); }); }); }); }
Usando el método putObject(), cargaremos archivos al depósito S3. En putObject(), necesitamos pasar el nombre del depósito al que cargaremos los archivos. Tenga en cuenta que, según las políticas de su depósito, puede enviar parámetros en putObject(). En este ejemplo, configuré la política de ACL predefinida en public-read (lectura pública). Asegúrese de verificar sus políticas de bucket de S3.
Tenga en cuenta que he utilizado variables de entorno para información confidencial, como ID de clave de acceso, clave secreta, etc. Si las variables están configuradas según lo recomendado por AWS, no es necesario que se pasen explícitamente al cliente S3 como se indicó anteriormente. El cliente S3 detecta automáticamente las variables de entorno configuradas.
Ahora, podemos iniciar el servidor y probar nuestro punto final POST. Aquí hay un ejemplo de Postman.
Una vez que la solicitud es exitosa, podemos ver el archivo en el depósito de S3.
Entrega de archivos a través de Amazon CloudFront
Anteriormente, descargamos la clave privada de los pares de claves de CloudFront. Usaremos esa clave privada y el ID de la clave de acceso para acceder a CloudFront en Node.js.
El controlador para el punto final de la API de descarga es el siguiente.
export async function download(req, res) { let response = await getFileLink(req.query.filename); res.send(response); res.end(); }
En este controlador, esperamos un nombre de archivo que debe descargarse a través de CloudFront.
Veamos cómo acceder a CloudFront en nuestra aplicación Node.js. Primero, instalaremos el módulo npm aws-cloudfront-sign. Con este módulo, podemos obtener URL firmadas de Amazon CloudFront, lo que nos permite proporcionar a los usuarios acceso a nuestro contenido privado. La URL firmada también contiene metainformación adicional, como la hora de vencimiento. Esto le da más control sobre el acceso a nuestro contenido.
export function getFileLink(filename) { return new Promise(function (resolve, reject) { var options = { keypairId: process.env.CLOUDFRONT_ACCESS_KEY_ID, privateKeyPath: process.env.CLOUDFRONT_PRIVATE_KEY_PATH }; var signedUrl = awsCloudFront.getSignedUrl(process.env.CLOUDFRONT_URL + filename, options); resolve(signedUrl); }); }
Aquí, necesitamos pasar el ID de la clave de acceso, la ruta al archivo de clave privada y la URL de CloudFront a getSignedURL(). La URL de CloudFront se vería así: https://XYZ.cloudfront.net. “XYZ” sería su nombre de distribución de CloudFront.
Inicie el servidor y pruebe el punto final GET de la siguiente manera:
Conclusión
En este artículo, vimos cómo cargar archivos en Amazon S3 y entregar esos archivos a través de Amazon CloudFront. Espero que hayas disfrutado de este artículo. Hágame saber si tiene algún comentario o sugerencia en la sección de comentarios a continuación.
El ejemplo de este artículo se puede encontrar en el repositorio de GitHub.
Este artículo se publicó originalmente en Techshard.com.