Presigned URL en S3

AWS - 10 de enero de 2022

¿Qué es una presigned url en S3?

Una presigned url es una url temporal que nos autoriza para subir o obtener un fichero en un bucket de S3.

Tener tus buckets de S3 privados es una buena práctica y las presigned url nos permite tener nuestros buckets privados mientras que podemos dar accesos temporales para realizar una única acción a un objeto en concreto.

Implementación

Es la hora de ver el código para generar una presigned url, pero antes déjame que te dé un par de consejos que te van a ahorrar mucho tiempo:

  • Si necesitas subir archivos de más de 10MB, tienes que utilizar una subida multi-part.
  • Las presigned url solo soportan el getObject y el putObject de un objeto de S3.
  • Por defecto, la url expira en 15 minutos, te recomiendo que ajustes el tiempo según el uso que le vayas a dar.
  • A la hora de utilizar la presigned url, tienes que tener en cuenta que debes enviar las mismas cabeceras que has definido a la hora de generarla, como por ejemplo el ContentType.

Inicialización

import AWS from 'AWS'

const s3 = new AWS.S3({
  accessKeyId: {YOUR_ACCESS_KEY},
  secretAccessKey: {YOUR_SECRET_ACESS_KEY}
})

const params = {
  Bucket: BUCKET_NAME,
  Key: OBJECT_NAME,
  ContentType: 'application/pdf', // content type del fichero
  Expires: 120 // en segundos
}

Crear presigned url para subir un fichero

const writePreSignedUrl = await s3.getSignedUrlPromise('putObject', params)

Crear presigned url para obtener un fichero

const readPresignedUrl = await s3.getSignedUrlPromise('getObject', params)

Utilizar presigned url para subir un fichero

import axios from 'axios'

axios.put(readSignedUrl, { // url generada anteriormente
  headers: {
    'Content-Type': 'application/pdf' // muy importante que sea el mismo content type
  }
})

Utilizar presigned url para obtener un fichero

import axios from 'axios'

axios.get(readSignedUrl, { // url generada anteriormente
  headers: {
    'Content-Type': 'application/pdf' // muy importante que sea el mismo content type
  }
})