Tutti i playbookNext.js + Supabase

Aggiungere una pagina protetta

Aggiungere una pagina riservata agli utenti autenticati o agli admin, con il controllo sul server e i dati protetti dalla RLS.

Quando usarlo

Una nuova pagina che possono aprire solo gli utenti autenticati, o solo gli admin: un'area account, una dashboard, le impostazioni.

Regole da rispettare

  • src/proxy.ts aggiorna la sessione e reindirizza a /login per rendere la navigazione più fluida. Non è il controllo d'accesso: la pagina verifica l'utente da sola e i dati sono protetti dalla RLS.
  • Identità e ruolo si risolvono sul server. Il ruolo arriva da profiles (member o admin); non leggerlo mai da query string, cookie o campi di un form.
  • Le pagine che leggono dati dell'utente sono Server Component. Usa un Client Component solo per le parti interattive e passagli i dati come props.

Passi

  1. Crea src/app/<percorso>/page.tsx come Server Component asincrono e inizialo come src/app/page.tsx:

    import { redirect } from "next/navigation";
    import { createClient } from "@/lib/supabase/server";
    
    export default async function AccountPage() {
      const supabase = await createClient();
      const { data: { user } } = await supabase.auth.getUser();
      if (!user) redirect("/login");
      // ...
    }
    

    Usa getUser(), che convalida la sessione con Supabase, non getSession(), che legge soltanto il cookie.

  2. Per una pagina admin, leggi il ruolo dopo il controllo dell'utente e fermati con notFound(), così la pagina non rivela di esistere:

    const { data: profile } = await supabase
      .from("profiles")
      .select("role")
      .eq("id", user.id)
      .single();
    if (profile?.role !== "admin") notFound();
    
  3. Controlla il proxy. In questa foundation updateSession (src/lib/supabase/middleware.ts) manda a /login ogni percorso tranne /register, /login e /auth quando manca la sessione, quindi una nuova pagina è già coperta. Se il file definisce un elenco di prefissi protetti, come fanno i prodotti costruiti su questa foundation, aggiungi lì il nuovo prefisso.

  4. Carica i dati con lo stesso client supabase: le query girano come l'utente e la RLS si applica. Se la pagina ha bisogno di una nuova tabella, segui prima il playbook "Aggiungere una tabella con RLS".

  5. Le modifiche passano da una Server Action o da un Route Handler che ripete il controllo getUser(), e quello del ruolo per le azioni admin: si possono chiamare anche senza aprire la pagina.

  6. Collega la pagina dalla navigazione solo per chi può aprirla. Se apre una nuova area del prodotto, descrivila in ARCHITECTURE.md.

Completato quando

  • i comandi di verifica passano;
  • senza sessione la pagina reindirizza a /login;
  • per una pagina admin, un account member riceve un 404;
  • ogni Server Action o Route Handler usato dalla pagina verifica di nuovo l'utente.