У меня стоит следующая задача:
Нужно создавать экскурсию с фото. Фото храним в Yandex Cloud S3
Загружать файлы на бэк не собираюсь для избежания DOS по памяти/CPU. Поэтому идея следующая: фронт с бэка получает временную ссылку для загрузки файла в S3 (поправьте, если это неверный паттерн: раньше таким не занимался).
Но для того, чтобы юзеры не могли засорить S3 файлами, которые не используются, мне
необходимо загружать файлы так, чтобы они удалились из S3 через некоторое время (если их не переместить в другую папку, например).
Сейчас есть вот так:
import { S3Client } from "@aws-sdk/client-s3";
import { Injectable } from "@nestjs/common";
@Injectable()
export class S3ClientService {
public client: S3Client;
constructor() {
this.client = new S3Client({
region: "ru-central1",
endpoint: "https://storage.yandexcloud.net",
credentials: {
accessKeyId: process.env.YC_S3_KEY_ID!,
secretAccessKey: process.env.YC_S3_SECRET!,
},
});
}
}
import { Injectable } from "@nestjs/common";
import { S3ClientService } from "./s3-client.service";
import { PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
@Injectable()
export class S3Service {
constructor(
private readonly s3: S3ClientService
) { }
async GetUploadUrl(key: string, contentType?: string) {
const command = new PutObjectCommand({
Bucket: process.env.YC_S3_BUCKET,
Key: key,
ContentType: contentType ?? 'application/octet-stream'
});
const url = await getSignedUrl(this.s3.client, command, {
expiresIn: 3600
});
const objectKey = key.split('/')[1];
return { url, key: objectKey };
}
}
То есть файл по этой ссылке просто загрузиться и будет сидеть в хранилище