Das Problem
Ich muss Bild-URLs serverseitig signieren, weil:
- Das Kryptomodul funktioniert nicht im Browser
- Der Signaturschlüssel/Salt muss geheim bleiben (nicht dem Client zugänglich gemacht)
- Nur zulassen der Server zum Verarbeiten von Bildern mit imgproxy (kein öffentlicher Endpunkt)
Mein Setup
Benutzerdefinierter imgproxy-Anbieter (~/providers/imgproxy.ts):
Code: Select all
import { createHmac } from "crypto";
import { defineProvider } from "@nuxt/image/runtime";
export default defineProvider({
getImage(src, { modifiers = {}, baseURL, key, salt }) {
// Sign URL using HMAC-SHA256
const signedPath = generateSignedPath(src, modifiers, key, salt);
return { url: `${baseURL}${signedPath}` };
},
});
Ausprobierte Ansätze
- Serverkomponente (Image.server.vue)
Die Bildkomponente wurde zu einer Serverkomponente gemacht, sodass das Signieren nur auf dem Server erfolgt.
Problem: Nuxt-Inseln rufen ihre HTML-Nutzlast während der Hydratation ab (/__nuxt_island/...), was bewirkt, dass der Browser den HTML-Code erneut analysiert und jedes Bild zweimal abruft. - API-Endpunkt umleiten
Der Anbieter gibt /api/imgproxy-sign?src=... zurück, die API signiert die URL und gibt eine 302-Weiterleitung zurück.
Problem: Warnung zu Hydrationskonflikten, da der Server /api/imgproxy-sign?... rendert, der Client jedoch dieselbe (oder eine andere) URL erwartet. Außerdem ist die Umleitung auf der Registerkarte „Netzwerk“ sichtbar und erhöht die Latenz.
- URLs nur auf dem Server signieren (Krypto im Browser nicht verwenden)
- Geheimnisse (Schlüssel/Salz) auf dem Server behalten
- Keine Warnungen zu Flüssigkeitskonflikten
- Bilder sollten nur abgerufen werden einmal (keine doppelten Anfragen)
- Idealerweise keine Weiterleitung – direkt signierte URLs in HTML
- Funktioniert sowohl für das anfängliche Laden von SSR als auch für die clientseitige Navigation
Gibt es eine Möglichkeit, @nuxt/image mit serverseitiger URL-Signatur zu verwenden, die:
- die gleiche URL auf dem Server erzeugt und Client (keine Nichtübereinstimmung der Flüssigkeitszufuhr)
- Verursacht keine doppelten Bildabrufe
- Behält Geheimnisse auf dem Server
Umgebung:
- Nuxt 3.x
- @nuxt/image Latest
- imgproxy (selbst gehostet)
Mobile version