In der Kategorie Fuckup der Woche geht es heute um ein Beispiel, das zeigt, wie viel Zeit man in etwas scheinbar Simples wie eine Proxy-Konfiguration investieren kann – und warum das am Ende lehrreich war.
Problem: Ein Proxy für eine API sollte lokale Anfragen weiterleiten, und dabei traten wiederholt 403 Forbidden
-Fehler auf. Die Ursache? Ein unscheinbarer Origin
-Header, den wir (fast) übersehen hätten.
Unser Setup basierte auf Vite
, einem beliebten Build-Tool für moderne Frontend-Entwicklung. Die Herausforderung bestand darin, einen Proxy zu konfigurieren, der Anfragen von einem lokalen Frontend an einen entfernten Server (TARGET_URL
) weiterleitet, ohne an selbstsignierten SSL-Zertifikaten oder Cross-Origin Resource Sharing (CORS)-Problemen zu scheitern. Der Proxy sollte:
secure: false
setzen, um Zertifikatsfehler zu umgehen.OPTIONS
) unterstützen und die richtigen Header setzen.^/centerdevice-rest-server/v2/ai-search
sollten umgeleitet und die Basispfade korrekt angepasst werden.Mit unserer Proxy-Konfiguration standen wir am Anfang vor einem ständigen 403 Forbidden
-Fehler. Trotz gefühlt endloser Anpassungen von changeOrigin
, secure
, und rewrite
, konnte der Proxy die Anfrage einfach nicht durchbringen. Der Server lehnte die Anfrage weiterhin ab, als ob wir an ein unsichtbares Hindernis stießen.
Was wir ausprobiert haben:
403
-Fehler durch fehlende CORS-Header verursacht wurde. Also ergänzten wir Access-Control-Allow-Origin
, Access-Control-Allow-Methods
, und Access-Control-Allow-Headers
.OPTIONS
-Antwort hinzu, um den Browser zufriedenzustellen, der jedes Mal mit einem Preflight-Test das Feld abfragte.changeOrigin: true
, damit der Proxy alle Anfragen so weiterleitete, als ob sie vom Ziel-Host kämen. Doch der Server blieb stur.Origin
-Header entfernenNach einer ausgiebigen Inspektion von curl
-Befehlen und einer genauen Überprüfung der Proxy-Req
-Header fiel uns ein unscheinbarer Verdächtiger auf: der Origin
-Header. Anders als curl
, das ohne diesen Header arbeitet, schickte der Proxy ihn hartnäckig mit. Das Problem: Der entfernte Server akzeptierte die Anfragen nur, wenn der Origin
-Header weggelassen wurde. Eine Regel, die in der API-Dokumentation nicht erwähnt war und die nur durch Ausschlussverfahren herauszufinden war.
Also: proxyReq.removeHeader("origin");
Sobald wir den Origin
-Header entfernt hatten, war der Weg frei. Kein 403
mehr. Die Anfrage ging durch, als wäre nie etwas gewesen.
Hier ist der endgültige Proxy-Setup in vite.config.js
, der das Problem umgeht, indem der Origin
-Header explizit entfernt wird und alle notwendigen CORS- und Fehler-Handler berücksichtigt:
import { defineConfig } from "vite";
import dotenv from "dotenv";
dotenv.config();
export default defineConfig({
server: {
port: process.env.PORT || 5000,
proxy: {
"^/derkuba-rest-server/v2/ai-search": {
target: process.env.TARGET_URL,
changeOrigin: true,
secure: false,
rewrite: (path) =>
path.replace(/^\/derkuba-rest-server\/v2\/ai-search/, ""),
configure: (proxy) => {
// Setzt CORS-Header für jede Anfrage
proxy.on("proxyReq", (proxyReq, req, res) => {
proxyReq.removeHeader("origin"); // Entfernt den Origin-Header
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS",
);
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization",
);
console.log(
`[Incoming Request] ${req.method} ${req.url}`,
);
console.log(
`[Outgoing Request] ${proxyReq.method} ${proxyReq.getHeader("host")}${proxyReq.path}`,
);
});
// Preflight-Anfragen für CORS beantworten
proxy.on("proxyRes", (proxyRes, req, res) => {
if (req.method === "OPTIONS") {
res.writeHead(200, {
"Content-Type": "text/plain",
});
res.end();
}
});
// Fehler-Handler mit CORS und Content-Type
proxy.on("error", (err, req, res) => {
console.error(`Proxy error: ${err.message}`);
if (res && !res.headersSent) {
res.writeHead(500, {
"Content-Type": "text/plain",
"Access-Control-Allow-Origin": "*",
});
res.end("Something went wrong with the proxy.");
}
});
},
},
},
},
});
Der Origin
-Header mag unscheinbar sein, kann aber bei serverseitigen API-Beschränkungen den Unterschied zwischen Erfolg und einem 403 Forbidden
-Fehler machen. Der heutige Fuckup der Woche ist eine Erinnerung daran, dass die kleinen Details oft die entscheidenden sind. Manchmal liegt die Lösung in der genauen Untersuchung des Request-Formats und in der geduldigen Fehlersuche – und nicht immer in großen Codeänderungen.
Für Feedback bin ich immer dankbar. Gerne an jacob@derkuba.de
Viele Grüße
Euer Kuba