---
title: "Wie man vorab signierte URLs für Supabase Storage mit Astro auf Cloudflare Workers generiert"
description: "Wie generiert man vorab signierte URLs, um Daten von Supabase Storage abzurufen und hochzuladen, mit Astro auf Cloudflare Workers?"
source: "https://www.launchfa.st/de/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" />

In diesem Leitfaden erfahren Sie, wie Sie vorab signierte URLs für Supabase Storage mit Astro auf Cloudflare Workers generieren. Sie werden den Prozess durchlaufen, ein neues Astro-Projekt einzurichten, serverseitiges Rendering mit dem Cloudflare-Adapter zu aktivieren, Supabase-Anmeldeinformationen zu erhalten und dann Funktionen zu erstellen, um vorab signierte URLs für den Abruf und das Hochladen von Supabase Storage zu generieren.

## Voraussetzungen

Um mitzumachen, benötigen Sie:

- [Node.js 20](https://nodejs.org/en) oder später
- Ein [Supabase](https://supabase.com/) Konto

## Inhaltsverzeichnis

- [Erstellen einer neuen Astro-Anwendung](#create-a-new-astro-application)
- [Integration des Cloudflare-Adapters in Ihr Astro-Projekt](#integrate-cloudflare-adapter-in-your-astro-project)
- [Erstellen eines Supabase-Projekts](#create-a-supabase-project)
- [Konfigurieren des Supabase Storage Buckets](#configure-supabase-storage-bucket)
- [Konfigurieren der Supabase Storage RLS-Richtlinien](#configure-supabase-storage-rls-policies)
- [Generieren der vorab signierten URLs](#generate-the-pre-signed-urls)
  - [1. Zugriff auf die Umgebungsvariablen](#1-access-the-environment-variables)
  - [2. Vorab signierte URL zum Abrufen eines Storage-Objekts (retrieve)](#2-generate-pre-signed-url-to-get-a-storage-object-retrieve)
  - [3. Vorab signierte URL zum Hochladen eines Storage-Objekts (upload)](#3-generate-pre-signed-url-to-put-a-storage-object-upload)
  - [4. Erstellen eines Server-Endpunkts (einer API-Route) in Astro](#4-create-a-server-endpoint-an-api-route-in-astro)
- [Bereitstellung auf Cloudflare Workers](#deploy-to-cloudflare-workers)

## Erstellen einer neuen Astro-Anwendung

Lassen Sie uns beginnen, indem wir ein neues Astro-Projekt erstellen. Öffnen Sie Ihr Terminal und führen Sie den folgenden Befehl aus:

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

`npm create astro` ist die empfohlene Methode, um schnell ein Astro-Projekt zu erstellen.

Wenn Sie dazu aufgefordert werden, wählen Sie:

- `Use minimal (empty) template`, wenn Sie gefragt werden, wie Sie das neue Projekt starten möchten.
- `Yes`, wenn Sie gefragt werden, ob Abhängigkeiten installiert werden sollen.
- `Yes`, wenn Sie gefragt werden, ob ein Git-Repository initialisiert werden soll.

Sobald das erledigt ist, können Sie in das Projektverzeichnis wechseln und die App starten:

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

Die App sollte auf [localhost:4321](http://localhost:4321/) laufen. Führen Sie als Nächstes den folgenden Befehl aus, um die erforderliche Bibliothek für den Aufbau der Anwendung zu installieren:

```bash
npm install
```

Es werden keine zusätzlichen Bibliotheken benötigt, da wir die native `fetch`-API verwenden, um direkt mit der REST-API von Supabase zu kommunizieren.

## Integration des Cloudflare-Adapters in Ihr Astro-Projekt

Um vorab signierte URLs für jedes Objekt dynamisch zu generieren, aktivieren Sie serverseitiges Rendering in Ihrem Astro-Projekt über den Cloudflare-Adapter. Führen Sie den folgenden Befehl aus:

```bash
npx astro add cloudflare
```

Wenn Sie dazu aufgefordert werden, wählen Sie Folgendes:

- `Y`, wenn Sie gefragt werden, ob die Cloudflare-Abhängigkeiten installiert werden sollen.
- `Y`, wenn Sie gefragt werden, ob Änderungen an der Astro-Konfigurationsdatei vorgenommen werden sollen.

Sie haben das serverseitige Rendering in Astro erfolgreich aktiviert.

Um sicherzustellen, dass die Ausgabe auf Cloudflare Workers bereitgestellt werden kann, erstellen Sie eine `wrangler.toml`-Datei im Stammverzeichnis des Projekts mit dem folgenden Code:

```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=""
```

Stellen Sie danach sicher, dass Sie sowohl eine `.env`-Datei als auch eine `wrangler.toml`-Datei mit den definierten Variablen haben, damit sie während `npm run dev` und bei der Bereitstellung auf Cloudflare Workers zugänglich sind.

Aktualisieren Sie außerdem die `astro.config.mjs`-Datei mit dem folgenden Code, um diese Variablen im Code programmatisch zugänglich zu machen:

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

// ... Existing imports...
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 }),
    }
  }
  // adapter
})
```

## Erstellen eines Supabase-Projekts

1. Gehen Sie zu [supabase.com](https://supabase.com/) und melden Sie sich in Ihrem Konto an.

2. Klicken Sie auf **New Project**, um ein neues Projekt zu erstellen.

3. Füllen Sie die Projektdetails aus:
   - **Name**: Wählen Sie einen Namen für Ihr Projekt
   - **Database Password**: Legen Sie ein sicheres Passwort für Ihre Datenbank fest
   - **Region**: Wählen Sie eine Region, die Ihren Nutzern am nächsten liegt

4. Klicken Sie auf **Create new project** und warten Sie, bis das Projekt eingerichtet ist.

5. Sobald das Projekt bereit ist, gehen Sie in Ihrem Projekt-Dashboard zur Registerkarte **Settings**.

6. Navigieren Sie zum Abschnitt **API Keys**, um Ihren API-Schlüssel zu finden, und kopieren Sie den folgenden Wert:
   - **anon public** key (dies wird Ihr `SUPABASE_ANON_KEY`)

7. Navigieren Sie zum Abschnitt **Data API**, um Ihre Projekt-URL zu finden, und kopieren Sie den folgenden Wert:
   - **Project URL** (dies wird Ihr `SUPABASE_URL`)


## Konfigurieren des Supabase Storage Buckets

1. Navigieren Sie in Ihrem Supabase-Dashboard in der linken Seitenleiste zu **Storage**.

2. Klicken Sie auf **Create a new bucket**.

3. Geben Sie einen Bucket-Namen ein (dies wird Ihr `SUPABASE_BUCKET_NAME`-Wert).

4. Wählen Sie, ob der Bucket öffentlich oder privat sein soll:
   - **Public**: Dateien können von jedem mit der URL abgerufen werden
   - **Private**: Dateien erfordern eine Authentifizierung für den Zugriff

5. Klicken Sie auf **Create bucket**.

## Konfigurieren der Supabase Storage RLS-Richtlinien

Row Level Security (RLS)-Richtlinien steuern den Zugriff auf Ihre Storage-Buckets. Für vorab signierte URLs müssen Sie Richtlinien erstellen, die authentifizierten Nutzern das Hochladen und Herunterladen von Dateien erlauben.

1. Gehen Sie in Ihrem Supabase-Dashboard zu **Storage** > **Policies**.

2. Wählen Sie Ihren Bucket aus und klicken Sie auf **New Policy**.

3. Für Upload-Zugriff erstellen Sie eine Richtlinie mit den folgenden Einstellungen:
   - Policy Name: **Allow authenticated uploads**
   - Allowed Operations: **INSERT**
   - Target roles: **anon**
   - Policy Definition: **bucket_id = 'your-bucket-name'**

4. Für Download-Zugriff erstellen Sie eine weitere Richtlinie:
   - Policy Name: **Allow authenticated downloads**
   - Allowed Operations: **SELECT**
   - Target roles: **anon**
   - Policy Definition: **bucket_id = 'your-bucket-name'**

5. Klicken Sie auf **Review** und dann auf **Save policy**.

## Generieren der vorab signierten URLs

### 1. Zugriff auf die Umgebungsvariablen

Der erste Schritt besteht darin, während der Laufzeit auf die erforderlichen Umgebungsvariablen zuzugreifen, um mit der REST-API von Supabase zu kommunizieren. Ab [Astro 5.6 und darüber hinaus](https://astro.build/blog/astro-560/) ist die Methode, wie Sie Laufzeit-Umgebungsvariablen in Ihrem Code zugreifen möchten, die Verwendung der `getSecret`-Funktion aus `astro:env/server`, um die Dinge anbieterunabhängig zu halten. Dies ist entscheidend, um sensible Informationen sicher zu speichern, ohne sie in Ihre Anwendung zu hardcodieren. Sie werden die folgenden Variablen abrufen:

- Supabase Project URL
- Supabase Anon Key
- Supabase Storage Bucket Name

```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. Vorab signierte URL zum Abrufen eines Storage-Objekts (retrieve)

Die Funktion `getSupabaseObject` unten ruft die vorab signierte URL eines Objekts aus Supabase Storage über die REST-API ab. Sie generiert eine signierte URL, die Ihnen ermöglicht, die Datei für eine begrenzte Zeit sicher abzurufen.

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

// ...Existing Code...

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. Vorab signierte URL zum Hochladen eines Storage-Objekts (upload)

Die Funktion `uploadSupabaseObject` unten ist verantwortlich für die Generierung einer vorab signierten URL zum Hochladen einer Datei in Supabase Storage über die REST-API. Sie erstellt eine signierte URL, die Ihnen ermöglicht, Dateien sicher hochzuladen.

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

// ...Existing Code...

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. Erstellen eines Server-Endpunkts (einer API-Route) in Astro

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

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

// Define an asynchronous function named GET that accepts a request object.
export async function GET({ request }: APIContext) {
  // Extract the 'file' parameter from the request URL.
  const url = new URL(request.url)
  const file = url.searchParams.get('file')
  
  // Check if the 'file' parameter exists in the URL.
  if (file) {
    try {
      const filePublicURL = await getSupabaseObject(file)
      // Return a response with the image's public URL and a 200 status code.
      return new Response(filePublicURL)
    } catch (error: any) {
      // If an error occurs, log the error message and return a response with a 500 status code.
      const message = error.message || error.toString()
      console.log(message)
      return new Response(message, { status: 500 })
    }
  }
  // If the 'file' parameter is not found in the URL, return a response with a 400 status code.
  return new Response('Invalid Request.', { status: 400 })
}

export async function POST({ request }: APIContext) {
    // Extract the parameters from the request URL.
    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 {
      // Generate an upload URL for the file
      const uploadUrl = await uploadSupabaseObject({ name, type })
      // Return a success response with the upload URL
      return new Response(uploadUrl)
    } catch (error: any) {
      // If there was an error during the upload process, return a 500 response with the error message
      const message = error.message || error.toString()
      console.log(message)
      return new Response(message, { status: 500 })
    }
}
```

## Bereitstellung auf Cloudflare Workers

Um Ihre Anwendung auf Cloudflare Workers bereitstellbar zu machen, erstellen Sie eine Datei namens `.assetsignore` im `public`-Verzeichnis mit folgendem Inhalt:

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

Als Nächstes müssen Sie das Wrangler CLI verwenden, um Ihre Anwendung auf Cloudflare Workers bereitzustellen. Führen Sie den folgenden Befehl aus, um die Bereitstellung durchzuführen:

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

### Fazit

In diesem Blogbeitrag haben Sie gelernt, wie Sie Supabase Storage mit Astro und Cloudflare Workers für Datei-Uploads und -Abrufe integrieren. Durch die Befolgung der Implementierungsschritte können Sie Dateien sicher in Supabase Storage hochladen und abrufen, wodurch Ihre Webanwendung eine robuste und flexible Speicherlösung erhält.

Wenn Sie bestimmte Abschnitte detaillierter erkunden, bestimmte Konzepte erweitern oder zusätzliche verwandte Themen behandeln möchten, lassen Sie es mich bitte wissen, und ich helfe Ihnen gerne weiter!
