Une route /admin sécurisée par HTTP Basic Auth, client Supabase service_role, et zéro dépendance supplémentaire.
Tout portfolio data-driven a besoin, à un moment, d'un moyen de surveiller ses propres données sans ouvrir le dashboard Supabase à chaque fois. Je voulais voir mes messages de contact, le nombre de projets et l'état de mes certifications en un coup d'œil — mais construire un système d'authentification complet m'a semblé totalement surdimensionné pour un outil personnel.
Le défi : comment protéger une route interne dans Next.js 16 sans aucune nouvelle dépendance, tout en pouvant lire des tables verrouillées par Row Level Security pour les utilisateurs anonymes ?
function adminAuth(request: NextRequest): NextResponse | null {
const expectedUser = process.env.ADMIN_USERNAME;
const expectedPass = process.env.ADMIN_PASSWORD;
if (!expectedUser || !expectedPass) {
return new NextResponse("Admin non configuré.", { status: 503 });
}
const authHeader = request.headers.get("authorization");
if (authHeader?.startsWith("Basic ")) {
try {
const decoded = atob(authHeader.slice(6)); // Edge-safe — sans Buffer
const colonIdx = decoded.indexOf(":");
if (colonIdx !== -1) {
const user = decoded.slice(0, colonIdx);
const pass = decoded.slice(colonIdx + 1);
if (user === expectedUser && pass === expectedPass) {
return null; // ✅ autorisé
}
}
} catch {
// base64 malformé — rejeter
}
}
return new NextResponse("Authentification requise.", {
status: 401,
headers: { "WWW-Authenticate": 'Basic realm="Admin", charset="UTF-8"' },
});
}