Wie man vorab signierte URLs für Cloudflare R2 mit Astro auf Cloudflare Workers generiert
LaunchFast Logo LaunchFast

Wie man vorab signierte URLs für Cloudflare R2 mit Astro auf Cloudflare Workers generiert

Rishi Raj Jain
How to Generate Pre-signed URLs for Cloudflare R2 with Cloudflare Workers

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

Hochwertige Starter-Kits mit integriertem Authentifizierungsfluss (Auth.js), Objekt-Uploads (AWS, Clouflare R2, Firebase Storage, Supabase Storage), integrierten Zahlungen (Stripe, LemonSqueezy), E-Mail-Verifizierungsablauf (Resend, Postmark, Sendgrid) und viel mehr . Kompatibel mit jeder Datenbank (Redis, Postgres, MongoDB, SQLite, Firestore).

Voraussetzungen

Um mitzumachen, benötigen Sie:

Inhaltsverzeichnis

Erstellen Sie eine neue 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:

Terminal window
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 dies abgeschlossen ist, können Sie in das Projektverzeichnis wechseln und die App starten:

Terminal window
cd my-app
npm run dev

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

Terminal window
npm install aws4fetch

Die folgende Bibliothek wird installiert:

  • aws4fetch: Ein AWS-Client für Umgebungen, die Fetch und SubtleCrypto unterstützen.

Integrieren Sie den Cloudflare-Adapter in Ihr Astro-Projekt

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

Terminal window
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:

wrangler.toml
name = "cloudflare-r2-astro-workers"
main = "dist/_worker.js"
compatibility_date = "2025-04-01"
compatibility_flags = [ "nodejs_compat" ]
[assets]
directory="dist"
binding="ASSETS"
[vars]
AWS_KEY_ID=""
AWS_S3_BUCKET_NAME=""
AWS_SECRET_ACCESS_KEY=""
CLOUDFLARE_R2_ACCOUNT_ID=""

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 entsprechend abgerufen werden können.

Aktualisieren Sie außerdem die astro.config.mjs-Datei mit dem Folgenden, um diese Variablen im Code programmatisch abrufen zu können:

astro.config.mjs
// ... Vorhandene Importe...
import { defineConfig, envField } from 'astro/config'
export default defineConfig({
env: {
schema: {
AWS_KEY_ID: envField.string({ context: 'server', access: 'secret', optional: false }),
AWS_S3_BUCKET_NAME: envField.string({ context: 'server', access: 'secret', optional: false }),
AWS_SECRET_ACCESS_KEY: envField.string({ context: 'server', access: 'secret', optional: false }),
CLOUDFLARE_R2_ACCOUNT_ID: envField.string({ context: 'server', access: 'secret', optional: false }),
}
}
// adapter
})

Einrichten von Cloudflare R2

  • Navigieren Sie zur Cloudflare R2-Übersichtsseite.
Head to the Cloudflare R2 Overview
  • Erstellen Sie einen neuen Bucket in Cloudflare R2 und speichern Sie den Namen als AWS_S3_BUCKET_NAME in den Umgebungsvariablen (.env & wrangler.toml).
Create a bucket in Cloudflare R2
  • Greifen Sie auf die R2-Kontodetails in Cloudflare R2 zu.
Open R2 Account Details in Cloudflare R2
  • Rufen Sie die Cloudflare R2-Konto-ID ab und speichern Sie sie als CLOUDFLARE_R2_ACCOUNT_ID in den Umgebungsvariablen (.env & wrangler.toml).
Grab the Cloudflare R2 Account ID
  • Erstellen Sie ein API-Token in Cloudflare R2.
Create an API token in Cloudflare R2
  • Erhalten Sie die Zugangs-Schlüssel-ID und den geheimen Zugangsschlüssel von Cloudflare R2 und speichern Sie sie als AWS_KEY_ID und AWS_SECRET_ACCESS_KEY in den Umgebungsvariablen (.env & wrangler.toml).
Grab the Access Key ID and Secret Access Key in Cloudflare R2

Generieren Sie die vorab signierten URLs

1. Zugriff auf die Umgebungsvariablen

Der erste Schritt besteht darin, während der Laufzeit auf die notwendigen Umgebungsvariablen zuzugreifen, um einen AWS-Client über aws4fetch zu erstellen. Ab Astro 5.6 und darüber hinaus ist die Methode, wie Sie auf 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 einzubetten. Sie werden die folgenden Variablen abrufen:

  • Cloudflare R2-Zugangs-Schlüssel-ID (als AWS_KEY_ID)
  • Cloudflare-Bucket-Name (als AWS_S3_BUCKET_NAME)
  • Cloudflare R2-Geheimer Zugangsschlüssel (als AWS_SECRET_ACCESS_KEY)
  • Cloudflare R2-Konto-ID (als CLOUDFLARE_R2_ACCOUNT_ID)
src/storage/r2.ts
import { getSecret } from 'astro:env/server'
const accessKeyId = getSecret('AWS_KEY_ID')
const s3BucketName = getSecret('AWS_S3_BUCKET_NAME')
const secretAccessKey = getSecret('AWS_SECRET_ACCESS_KEY')
const r2AccountId = getSecret('CLOUDFLARE_R2_ACCOUNT_ID')

2. Definieren Sie den AWS-Client

Als Nächstes definieren Sie die Funktion defineAws4Fetch, die eine AWS-Client-Instanz erstellt. Diese Funktion überprüft, ob die erforderlichen AWS-Anmeldeinformationen gesetzt sind, und gibt eine neue AwsClient-Instanz zurück, die für R2 konfiguriert ist.

src/storage/r2.ts
import { AwsClient } from 'aws4fetch'
// ...Vorhandener Code...
async function defineAws4Fetch(): Promise<AwsClient> {
if (!accessKeyId || !secretAccessKey) {
throw new Error(`AWS_KEY_ID OR AWS_SECRET_ACCESS_KEY environment variable(s) are not set.`)
}
return new AwsClient({
accessKeyId,
secretAccessKey,
service: 's3',
region: 'auto',
})
}

3. Bestimmen Sie R2-URLs

Sie müssen eindeutige URLs für jeden Datei-Upload zu Cloudflare R2 generieren. Die Funktion getR2URL unten kümmert sich um die Konstruktion der korrekten URL basierend auf dem Dateinamen und dem Bucket-Namen.

src/storage/r2.ts
// ...Vorhandener Code...
function getR2URL({ Key }: { Key: string }) {
if (!s3BucketName) {
throw new Error(`AWS_S3_BUCKET_NAME environment variable(s) are not set.`)
}
return new URL(`https://${r2AccountId}.r2.cloudflarestorage.com/${s3BucketName}/${Key}`)
}

4. Vorab signierte URL zum Abrufen eines R2-Objekts (abrufen)

Die Funktion getR2ObjectURL unten ruft die vorab signierte URL eines Objekts von Cloudflare R2 ab. Sie generiert eine signierte Anfrage, die Ihnen den sicheren Zugriff auf die Datei ermöglicht.

src/storage/r2.ts
// ...Vorhandener Code...
export async function getR2ObjectURL(Key: string) {
try {
const endpointUrl = getR2URL({ Key })
endpointUrl.searchParams.set('X-Amz-Expires', '3600')
const client = await defineAws4Fetch()
const signedRequest = await client.sign(new Request(endpointUrl), { aws: { signQuery: true } })
return signedRequest.url
} catch (e: any) {
const tmp = e.message || e.toString()
console.log(tmp)
return
}
}

5. Vorab signierte URL zum Hochladen eines R2-Objekts (hochladen)

Die Funktion uploadR2ObjectURL unten ist verantwortlich für die Generierung einer vorab signierten URL zum Hochladen einer Datei zu Cloudflare R2. Sie folgt einer ähnlichen Struktur wie die Funktion getR2ObjectURL und generiert eine signierte URL, die Ihnen das sichere Hochladen von Dateien ermöglicht.

export async function uploadR2ObjectURL(file: { name: string; type: string }) {
try {
const Key = file.name
const endpointUrl = getR2URL({ Key })
endpointUrl.searchParams.set('X-Amz-Expires', '3600')
const client = await defineAws4Fetch()
const signedRequest = await client.sign(new Request(endpointUrl, { method: 'PUT', headers: { 'Content-Type': file.type } }), { method: 'PUT', aws: { signQuery: true } })
return signedRequest.url
} catch (e: any) {
const tmp = e.message || e.toString()
console.log(tmp)
return
}
}

6. Erstellen Sie einen Server-Endpunkt (eine API-Route) in Astro

src/pages/api/storage.ts
import type { APIContext } from 'astro'
import { getR2ObjectURL, uploadR2ObjectURL } from '../../storage/r2'
// Definieren Sie eine asynchrone Funktion namens GET, die ein Anforderungsobjekt akzeptiert.
export async function GET({ request }: APIContext) {
// Extrahieren Sie den 'file'-Parameter aus der Anforderungs-URL.
const url = new URL(request.url)
const file = url.searchParams.get('file')
// Überprüfen Sie, ob der 'file'-Parameter in der URL vorhanden ist.
if (file) {
try {
const filePublicURL = await getR2ObjectURL(file)
// Geben Sie eine Antwort mit der öffentlichen URL des Bildes und einem 200-Statuscode zurück.
return new Response(filePublicURL)
} catch (error: any) {
// Wenn ein Fehler auftritt, protokollieren Sie die Fehlermeldung und geben Sie eine Antwort mit einem 500-Statuscode zurück.
const message = error.message || error.toString()
console.log(message)
return new Response(message, { status: 500 })
}
}
// Wenn der 'file'-Parameter in der URL nicht gefunden wird, geben Sie eine Antwort mit einem 400-Statuscode zurück.
return new Response('Invalid Request.', { status: 400 })
}
export async function POST({ request }: APIContext) {
// Extrahieren Sie den 'file'-Parameter aus der Anforderungs-URL.
const url = new URL(request.url)
const type = url.searchParams.get('type')
const name = url.searchParams.get('name')
if (!type || !name) return new Response('Invalid Request.', {status:400})
try {
// Generieren Sie eine zugängliche URL für die hochgeladene Datei
// Verwenden Sie diese URL, um einen GET an diesen Endpunkt mit dem Datei-Abfrage-Parameter zu senden, der wie unten angegeben ist
const publicUploadUrl = await uploadR2ObjectURL({ type, name })
// Geben Sie eine Erfolgsantwort mit einer Nachricht zurück
return new Response(publicUploadUrl)
} catch (error: any) {
// Wenn während des Upload-Prozesses ein Fehler auftritt, geben Sie eine 403-Antwort mit der Fehlermeldung zurück
const message = error.message || error.toString()
console.log(message)
return new Response(message, { status: 500 })
}
}

Bereitstellen 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:

Terminal window
npm run build && npx wrangler@latest deploy

Referenzen

Fazit

In diesem Blogbeitrag haben Sie gelernt, wie Sie Cloudflare R2 mit Astro und Cloudflare Workers für Datei-Uploads und -Abrufe integrieren. Durch das Befolgen der Implementierungsschritte können Sie Dateien sicher in Cloudflare R2 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!

Learn More Abfrage von Cloud Firestore mit Astro auf Cloudflare Workers
Abfrage von Cloud Firestore mit Astro auf Cloudflare Workers April 25, 2025
Abfrage von Redis mit Astro auf Cloudflare Workers
Abfrage von Redis mit Astro auf Cloudflare Workers April 25, 2025
Wie man vorab signierte URLs für Firebase Storage mit Astro auf Cloudflare Workers generiert
Wie man vorab signierte URLs für Firebase Storage mit Astro auf Cloudflare Workers generiert April 24, 2025