---
title: "Cómo generar URLs pre-firmadas para Supabase Storage con Astro en Cloudflare Workers"
description: "¿Cómo se generan URLs pre-firmadas para recuperar y subir datos desde Supabase Storage, usando Astro en Cloudflare Workers?"
source: "https://www.launchfa.st/es/blog/supabase-storage-cloudflare-workers"
author: "Rishi Raj Jain"
created_at: 2025-04-25T00:00:00.000Z
---

> **Site index for agents**
> Fetch https://www.launchfa.st/llms.txt to discover every page on this site.
> Every page is also available as Markdown by appending `.md` to its URL.

<img width="1600" height="900" alt="How to Generate Pre-signed URLs for Supabase Storage with Cloudflare Workers" decoding="async" loading="eager" class="mt-4 border rounded-sm bg-cover bg-center bg-no-repeat transform will-change-auto" src="https://ik.imagekit.io/vjeqenuhn/launchfast-website/supabase-storage-cloudflare-workers.png" />

<a href="/#pricing" class="rounded-full break-words text-xs border text-black px-4 py-2 max-w-max text-center no-underline hover:bg-black hover:text-white">
  ℹ️&nbsp;&nbsp;Available today with LaunchFast Starter Kits</a>
</div>

En esta guía, aprenderás a generar URLs pre-firmadas para Supabase Storage con Astro en Cloudflare Workers. Pasarás por el proceso de configurar un nuevo proyecto Astro, habilitar la renderización del lado del servidor usando el adaptador de Cloudflare, obtener las credenciales de Supabase y luego crear funciones para generar URLs pre-firmadas para la recuperación y carga desde Supabase Storage.

## Requisitos previos

Para seguir, necesitarás:

- [Node.js 20](https://nodejs.org/en) o posterior
- Una cuenta de [Supabase](https://supabase.com/)

## Tabla de Contenidos

- [Crear una nueva aplicación Astro](#crear-una-nueva-aplicación-astro)
- [Integrar el adaptador de Cloudflare en tu proyecto Astro](#integrar-el-adaptador-de-cloudflare-en-tu-proyecto-astro)
- [Crear un proyecto Supabase](#crear-un-proyecto-supabase)
- [Configurar el Bucket de Supabase Storage](#configurar-el-bucket-de-supabase-storage)
- [Configurar las Políticas RLS de Supabase Storage](#configurar-las-políticas-rls-de-supabase-storage)
- [Generar las URLs pre-firmadas](#generar-las-urls-pre-firmadas)
  - [1. Acceder a las Variables de Entorno](#1-acceder-a-las-variables-de-entorno)
  - [2. URL Pre-firmada para GET un Objeto de Storage (recuperar)](#2-url-pre-firmada-para-get-un-objeto-de-storage-recuperar)
  - [3. URL Pre-firmada para PUT un Objeto de Storage (cargar)](#3-url-pre-firmada-para-put-un-objeto-de-storage-cargar)
  - [4. Crear un Endpoint del Servidor (una Ruta API) en Astro](#4-crear-un-endpoint-del-servidor-una-ruta-api-en-astro)
- [Desplegar en Cloudflare Workers](#desplegar-en-cloudflare-workers)

## Crear una nueva aplicación Astro

Comencemos creando un nuevo proyecto Astro. Abre tu terminal y ejecuta el siguiente comando:

```bash
npm create astro@latest my-app
```

`npm create astro` es la forma recomendada de crear rápidamente un proyecto Astro.

Cuando se te pregunte, elige:

- `Use minimal (empty) template` cuando se te pregunte cómo iniciar el nuevo proyecto.
- `Yes` cuando se te pregunte si deseas instalar dependencias.
- `Yes` cuando se te pregunte si deseas inicializar un repositorio git.

Una vez hecho esto, puedes moverte al directorio del proyecto y comenzar la aplicación:

```bash
cd my-app
npm run dev
```

La aplicación debería estar ejecutándose en [localhost:4321](http://localhost:4321/). A continuación, ejecuta el siguiente comando para instalar la biblioteca necesaria para construir la aplicación:

```bash
npm install
```

No se necesitan bibliotecas adicionales, ya que usaremos la API nativa `fetch` para comunicarnos directamente con la API REST de Supabase.

## Integrar el adaptador de Cloudflare en tu proyecto Astro

Para generar URLs pre-firmadas para cada objeto dinámicamente, habilitarás la renderización del lado del servidor en tu proyecto Astro a través del adaptador de Cloudflare. Ejecuta el siguiente comando:

```bash
npx astro add cloudflare
```

Cuando se te pregunte, elige lo siguiente:

- `Y` cuando se te pregunte si deseas instalar las dependencias de Cloudflare.
- `Y` cuando se te pregunte si deseas realizar cambios en el archivo de configuración de Astro.

Has habilitado con éxito la renderización del lado del servidor en Astro.

Para asegurarte de que la salida sea desplegable en Cloudflare Workers, crea un archivo `wrangler.toml` en la raíz del proyecto con el siguiente código:

```toml
// File: wrangler.toml

name = "supabase-storage-astro-workers"
main = "dist/_worker.js"
compatibility_date = "2025-04-01"
compatibility_flags = [ "nodejs_compat" ]

[assets]
directory="dist"
binding="ASSETS"

[vars]
SUPABASE_URL=""
SUPABASE_ANON_KEY=""
SUPABASE_BUCKET_NAME=""
```

Después de eso, asegúrate de tener tanto un archivo `.env` como un archivo `wrangler.toml` con las variables definidas para que puedan ser accedidas durante `npm run dev` y cuando se despliegue en Cloudflare Workers respectivamente.

Además, actualiza el archivo `astro.config.mjs` con lo siguiente para poder acceder a estas variables en el código de manera programática:

```tsx
// File: astro.config.mjs

// ... Importaciones existentes...
import { defineConfig, envField } from 'astro/config'

export default defineConfig({
  env: {
    schema: {
      SUPABASE_URL: envField.string({ context: 'server', access: 'secret', optional: false }),
      SUPABASE_ANON_KEY: envField.string({ context: 'server', access: 'secret', optional: false }),
      SUPABASE_BUCKET_NAME: envField.string({ context: 'server', access: 'secret', optional: false }),
    }
  }
  // adaptador
})
```

## Crear un proyecto Supabase

1. Ve a [supabase.com](https://supabase.com/) e inicia sesión en tu cuenta.

2. Haz clic en **New Project** para crear un nuevo proyecto.

3. Completa los detalles del proyecto:
   - **Name**: Elige un nombre para tu proyecto
   - **Database Password**: Establece una contraseña segura para tu base de datos
   - **Region**: Selecciona la región más cercana a tus usuarios

4. Haz clic en **Create new project** y espera a que el proyecto se configure.

5. Una vez que el proyecto esté listo, ve a la pestaña **Settings** en el panel de tu proyecto.

6. Navega a la sección **API Keys** para encontrar tu clave API y copia el siguiente valor:
   - Clave **anon public** (esta será tu `SUPABASE_ANON_KEY`)

7. Navega a la sección **Data API** para encontrar la URL de tu proyecto y copia el siguiente valor:
   - **Project URL** (esta será tu `SUPABASE_URL`)


## Configurar el Bucket de Supabase Storage

1. En el panel de Supabase, navega a **Storage** en la barra lateral izquierda.

2. Haz clic en **Create a new bucket**.

3. Introduce un nombre para el bucket (este será el valor de tu `SUPABASE_BUCKET_NAME`).

4. Elige si el bucket debe ser público o privado:
   - **Public**: Cualquier persona con la URL puede acceder a los archivos
   - **Private**: Los archivos requieren autenticación para acceder

5. Haz clic en **Create bucket**.

## Configurar las Políticas RLS de Supabase Storage

Las políticas de Row Level Security (RLS) controlan el acceso a tus buckets de almacenamiento. Para las URLs pre-firmadas, necesitarás crear políticas que permitan a los usuarios autenticados subir y descargar archivos.

1. En el panel de Supabase, ve a **Storage** > **Policies**.

2. Selecciona tu bucket y haz clic en **New Policy**.

3. Para el acceso de carga, crea una política con la siguiente configuración:
   - Policy Name: **Allow authenticated uploads**
   - Allowed Operations: **INSERT**
   - Target roles: **anon**
   - Policy Definition: **bucket_id = 'your-bucket-name'**

4. Para el acceso de descarga, crea otra política:
   - Policy Name: **Allow authenticated downloads**
   - Allowed Operations: **SELECT**
   - Target roles: **anon**
   - Policy Definition: **bucket_id = 'your-bucket-name'**

5. Haz clic en **Review** y luego en **Save policy**.

## Generar las URLs pre-firmadas

### 1. Acceder a las Variables de Entorno

El primer paso es acceder a las variables de entorno necesarias durante el tiempo de ejecución para comunicarse con la API REST de Supabase. Desde [Astro 5.6 y posteriores](https://astro.build/blog/astro-560/), la forma en que deseas acceder a las variables de entorno en tiempo de ejecución en tu código es utilizando la función `getSecret` de `astro:env/server` para mantener las cosas agnósticas al proveedor. Esto es crucial para almacenar información sensible de manera segura sin codificarla directamente en tu aplicación. Recuperarás las siguientes variables:

- URL del Proyecto Supabase
- Clave Anon de Supabase
- Nombre del Bucket de Supabase Storage

```typescript
// File: src/storage/supabase.ts

import { getSecret } from 'astro:env/server'

const body = JSON.stringify({ expiresIn: 60 * 60 })

const SUPABASE_URL = getSecret('SUPABASE_URL')
const SUPABASE_BASE_STORAGE_API = `${SUPABASE_URL}/storage/v1`

const headers = new Headers()
headers.append('x-upsert', 'true')
headers.append('Content-Type', 'application/json')
headers.append('Authorization', `Bearer ${getSecret('SUPABASE_ANON_KEY')}`)
```

### 2. URL Pre-firmada para GET un Objeto de Storage (recuperar)

La función `getSupabaseObject` a continuación recupera la URL pre-firmada de un objeto desde Supabase Storage usando la API REST. Genera una URL firmada que te permite acceder al archivo de manera segura durante un tiempo limitado.

```typescript
// File: src/storage/supabase.ts

// ...Código existente...

export async function getSupabaseObject(objectPath: string) {
  try {
    const objectCall = await fetch(`${SUPABASE_BASE_STORAGE_API}/object/sign/${getSecret('SUPABASE_BUCKET_NAME')}/${objectPath}`, {
      body,
      headers,
      method: 'POST',
    })
    const objectResp = await objectCall.json()
    if (!objectCall.ok) throw new Error(JSON.stringify(objectResp))
    return [SUPABASE_BASE_STORAGE_API, objectResp.signedURL].join('')
  } catch (e: any) {
    const tmp = e.message || e.toString()
    console.log(tmp)
    return
  }
}
```

### 3. URL Pre-firmada para PUT un Objeto de Storage (cargar)

La función `uploadSupabaseObject` a continuación es responsable de generar una URL pre-firmada para cargar un archivo a Supabase Storage usando la API REST. Crea una URL firmada que te permite cargar archivos de manera segura.

```typescript
// File: src/storage/supabase.ts

// ...Código existente...

export async function uploadSupabaseObject(file: { name: string; type: string }) {
  try {
    const objectCall = await fetch(`${SUPABASE_BASE_STORAGE_API}/object/upload/sign/${getSecret('SUPABASE_BUCKET_NAME')}/${file.name}`, {
      body,
      headers,
      method: 'POST',
    })
    const objectResp = await objectCall.json()
    if (!objectCall.ok) throw new Error(JSON.stringify(objectResp))
    return [SUPABASE_BASE_STORAGE_API, objectResp.url].join('')
  } catch (e: any) {
    const tmp = e.message || e.toString()
    console.log(tmp)
    return
  }
}
```

### 4. Crear un Endpoint del Servidor (una Ruta API) en Astro

```tsx
// File: src/pages/api/storage.ts

import type { APIContext } from 'astro'
import { getSupabaseObject, uploadSupabaseObject } from '../../storage/supabase'

// Define una función asincrónica llamada GET que acepta un objeto de solicitud.
export async function GET({ request }: APIContext) {
  // Extrae el parámetro 'file' de la URL de la solicitud.
  const url = new URL(request.url)
  const file = url.searchParams.get('file')
  
  // Verifica si el parámetro 'file' existe en la URL.
  if (file) {
    try {
      const filePublicURL = await getSupabaseObject(file)
      // Devuelve una respuesta con la URL pública de la imagen y un código de estado 200.
      return new Response(filePublicURL)
    } catch (error: any) {
      // Si ocurre un error, registra el mensaje de error y devuelve una respuesta con un código de estado 500.
      const message = error.message || error.toString()
      console.log(message)
      return new Response(message, { status: 500 })
    }
  }
  // Si el parámetro 'file' no se encuentra en la URL, devuelve una respuesta con un código de estado 400.
  return new Response('Invalid Request.', { status: 400 })
}

export async function POST({ request }: APIContext) {
    // Extrae los parámetros de la URL de la solicitud.
    const url = new URL(request.url)
    const name = url.searchParams.get('name')
    const type = url.searchParams.get('type')
    
    if (!name || !type) {
      return new Response('Invalid Request. Missing name or type.', { status: 400 })
    }
    
    try {
      // Genera una URL de carga para el archivo
      const uploadUrl = await uploadSupabaseObject({ name, type })
      // Devuelve una respuesta de éxito con la URL de carga
      return new Response(uploadUrl)
    } catch (error: any) {
      // Si hubo un error durante el proceso de carga, devuelve una respuesta 500 con el mensaje de error
      const message = error.message || error.toString()
      console.log(message)
      return new Response(message, { status: 500 })
    }
}
```

## Desplegar en Cloudflare Workers

Para hacer que tu aplicación sea desplegable en Cloudflare Workers, crea un archivo llamado `.assetsignore` en el directorio `public` con el siguiente contenido:

```
_routes.json
_worker.js
```

A continuación, necesitarás usar la CLI de Wrangler para desplegar tu aplicación en Cloudflare Workers. Ejecuta el siguiente comando para desplegar:

```bash
npm run build && npx wrangler@latest deploy
```

### Conclusión

En este artículo, aprendiste cómo integrar Supabase Storage con Astro y Cloudflare Workers para cargas y recuperaciones de archivos. Siguiendo los pasos de implementación, puedes cargar y recuperar archivos de Supabase Storage de manera segura, asegurando que tu aplicación web tenga una solución de almacenamiento robusta y flexible.

Si deseas explorar secciones específicas con más detalle, ampliar ciertos conceptos o cubrir temas relacionados adicionales, por favor házmelo saber y estaré encantado de ayudarte.
