Большинство приложений сегодня обслуживают пользователей по всему миру и нуждаются в способе быстрой доставки своего контента. Контент может быть изображениями, видео, PDF и т. Д. Сеть доставки контента (CDN) - это сеть серверов, которые географически распределены с целью предоставления контента пользователям как можно быстрее.

Amazon CloudFront - это сетевой сервис доставки контента, который обеспечивает быструю и безопасную доставку контента. В этой статье я опишу, как загружать файлы в корзину S3 и обслуживать эти файлы через CloudFront в Node.js. CloudFront будет использовать S3 в качестве источника в этой статье.

Предпосылки

Создайте корзину в S3 и создайте раздачу CloudFront в AWS. В этой статье я не буду вдаваться в подробности создания корзины S3 и распространения CloudFront. Перейдите в IAM и перейдите в «Учетные данные безопасности» под пользователем. Создайте ключ доступа и загрузите файл CSV, если у вас его еще нет. Этот ключ доступа нам понадобится позже.

Затем нажмите «Мои учетные данные безопасности» под своей учетной записью.

В разделе «Пара ключей CloudFront» создайте пару ключей, загрузите закрытый ключ и запишите свой идентификатор ключа доступа. Они нам понадобятся позже для интеграции.

Создание приложения Node.js

Давайте создадим простой экспресс-сервер Node.js и добавим две конечные точки REST API для загрузки и скачивания файлов. Вот образец структуры проекта.

В этом примере проекта я использую модули npm typescript и ts-node-dev. Поэтому у меня в проекте есть tsconfig.json.

Вот весь файл app.ts. Файл содержит логику для инициализации экспресс-сервера и конечных точек REST. Я также использую модуль npm multer для обработки загрузки файлов из нескольких частей.

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);
    }
  };
}

Загрузка файлов в Amazon S3 Bucket

Давайте посмотрим, как загружать файлы в корзину S3. Нам нужно будет установить модуль узла aws-sdk для доступа к корзинам S3 из приложения Node.js.

После установки обработчик конечной точки загрузки определяется следующим образом:

export async function upload(req, res) {
  let response = await uploadFile(req.file.originalname, req.file.path);
  res.send(response);
  res.end();
}

В fileComponent.ts нам нужно импортировать модуль aws-sdk следующим образом.

import awsSDK from 'aws-sdk';

В начале статьи мы загрузили CSV-файл, содержащий идентификатор ключа доступа и секретный ключ доступа. Мы будем использовать их для загрузки файлов в корзину S3. Используя модуль aws-sdk, нам нужно настроить идентификатор ключа доступа и секретный ключ доступа следующим образом:

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");
      });
    });
  });
}

Используя метод putObject (), мы загрузим файлы в корзину S3. В putObject () нам нужно передать имя сегмента, в который мы будем загружать файлы. Обратите внимание, что в зависимости от политик сегмента вы можете отправлять параметры в putObject (). В этом примере я установил для стандартной политики ACL значение public-read. Обязательно проверьте политики корзины S3.

Обратите внимание, что я использовал переменные среды для конфиденциальной информации, такой как идентификатор ключа доступа, секретный ключ и так далее. Если переменные настроены в соответствии с рекомендациями AWS, их не нужно явно передавать клиенту S3, как указано выше. Клиент S3 автоматически определяет настроенные переменные среды.

Теперь мы можем запустить сервер и протестировать нашу конечную точку POST. Вот пример от Почтальона.

Как только запрос будет успешным, мы сможем увидеть файл в корзине S3.

Обслуживание файлов через Amazon CloudFront

Ранее мы загружали закрытый ключ из пары ключей CloudFront. Мы будем использовать этот закрытый ключ и идентификатор ключа доступа для доступа к CloudFront в Node.js.

Обработчик конечной точки API загрузки выглядит следующим образом.

export async function download(req, res) {
  let response = await getFileLink(req.query.filename);
  res.send(response);
  res.end();
}

В этом обработчике ожидается имя файла, который необходимо загрузить через CloudFront.

Давайте посмотрим, как получить доступ к CloudFront в нашем приложении Node.js. Сначала мы установим модуль npm aws-cloudfront-sign. Используя этот модуль, мы можем получить подписанные URL-адреса Amazon CloudFront, что позволяет нам предоставлять пользователям доступ к нашему личному контенту. Подписанный URL-адрес также содержит дополнительную метаинформацию, такую ​​как срок действия. Это дает больший контроль над доступом к нашему контенту.

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);
  });
}

Здесь нам нужно передать идентификатор ключа доступа, путь к файлу закрытого ключа и URL-адрес CloudFront в getSignedURL (). URL-адрес CloudFront будет выглядеть примерно так: https: // XYZ.cloudfront.net. ‘ XYZ’ будет вашим именем распространения CloudFront.

Запустите сервер и проверьте конечную точку GET следующим образом:

Заключение

В этой статье мы увидели, как загружать файлы в Amazon S3 и обслуживать эти файлы через Amazon CloudFront. Надеюсь, вам понравилась эта статья. Дайте мне знать, если у вас есть какие-либо комментарии или предложения в разделе комментариев ниже.

Пример для этой статьи можно найти в репозитории GitHub.

Эта статья изначально была размещена на Techshard.com.