modulo 04 / lezione 24
Architettura mentale di un'applicazione
API, autenticazione, autorizzazione, sessioni
Capire i concetti base che regolano accesso e scambio dati, prima di chiedere all'AI di implementarli.
API, autenticazione, autorizzazione, sessioni
Quattro concetti che chi inizia confonde sempre, e che il modello AI implementa con errori sistematici se non sai cosa stai chiedendo. API = contratto. Autenticazione = chi sei. Autorizzazione = cosa puoi fare. Sessione = continuità del tuo accesso. Sapere cosa è cosa permette di chiedere implementazioni corrette invece di generiche.
Perché questa lezione conta
Errori in questa area producono falle reali: token in localStorage rubabili via XSS, ruoli verificati solo lato client, autorizzazioni mancanti su endpoint, sessioni che non scadono. Sono errori comuni nei prototipi generati. Studiare i concetti — non i dettagli implementativi — ti permette di chiedere all’AI implementazioni sicure e di leggere il codice sapendo cosa cercare.
Obiettivo operativo
Alla fine devi saper:
- distinguere API, autenticazione, autorizzazione, sessione;
- progettare a parole un flusso login/logout e un endpoint protetto;
- identificare 5 anti-pattern di sicurezza tipici di prototipi AI.
Nucleo della lezione
1. API come contratto
Un’API (Application Programming Interface) è un contratto: un client manda una richiesta in un formato definito, riceve risposta in un formato definito.
Componenti:
- Endpoint: indirizzo + metodo.
GET /users/:id,POST /orders. - Request: metodo, URL, headers (incl. auth), query string, body. Dati in entrata.
- Response: status code, headers, body. Dati in uscita + segnale di esito.
- Status code: 2xx successo, 3xx redirect, 4xx errore client (richiesta sbagliata o non autorizzata), 5xx errore server.
- Errori: messaggio strutturato, leggibile da macchina. Mai esporre stack trace o dettagli interni.
- Versionamento: quando cambi un’API esistente, rompi i client. Versiona (
/v1/...,/v2/...) o estendi senza rompere.
Stili principali:
- REST: orientato a risorse, metodi HTTP standard. Maggioritario per molti casi.
- GraphQL: query flessibili, un endpoint, schema fortemente tipato. Utile per UI complesse.
- RPC (gRPC, JSON-RPC): orientato ad azioni. Usato in sistemi distribuiti interni.
Per la maggior parte dei progetti vibe coding, REST è il default ragionevole.
2. Autenticazione vs autorizzazione
Autenticazione (authn): dimostrare chi sei. Risponde a “sei davvero Carlo?”. Tipiche prove:
- password (cosa sai);
- magic-link via email (cosa hai accesso a);
- TOTP/codice da app (qualcosa che hai);
- biometria (qualcosa che sei);
- passkey/WebAuthn (combinazione di sopra, criptograficamente forte).
Esito: il server stabilisce identità. Genera un token o crea sessione.
Autorizzazione (authz): cosa puoi fare. Risponde a “Carlo può eliminare questa risorsa?”. Modelli tipici:
- Ruoli (RBAC): ogni utente ha 1+ ruoli (admin, editor, viewer); ogni ruolo ha permessi.
- Ownership: utente può modificare solo le sue risorse.
- Permessi granulari: regole esplicite per risorsa.
- Policy-based (ABAC): condizioni complesse (ruolo + attributo risorsa + contesto).
Errore comune: confondere i due. Se sei autenticato non significa che sei autorizzato a tutto. Server deve verificare entrambi.
3. Sessione
Una sessione mantiene l’identità autenticata fra più richieste, perché HTTP è stateless.
Due approcci principali:
Cookie + sessione lato server: server crea sessione, salva in DB/Redis, manda cookie al client (id sessione). Client invia cookie a ogni richiesta. Vantaggi: revoca facile, controllo totale. Cookie deve avere flags: HttpOnly (no JS access, anti-XSS), Secure (solo HTTPS), SameSite=Lax o Strict (anti-CSRF). Sessione scade lato server.
Token (JWT) lato client: server firma JWT con identità e permessi. Client invia token in header Authorization: Bearer ... a ogni richiesta. Vantaggi: stateless. Rischi: revoca difficile (token valido fino a scadenza), token in localStorage rubabile via XSS. Buone pratiche: token corto (15 min) + refresh token in cookie HttpOnly.
Per la maggior parte dei vibe-coding project: cookie + sessione server, gestita da auth provider (Auth.js / NextAuth, Clerk, Supabase Auth, Auth0). Implementare auth a mano è zona dove l’AI sbaglia spesso.
4. Anti-pattern tipici
Cinque errori che il modello AI tende a produrre:
- Token in localStorage: vulnerabile a XSS. Usa cookie HttpOnly.
- Ruoli solo lato client: client invia “io sono admin” e server fida. Sempre verificare lato server, derivando ruolo da sessione.
- Endpoint protetti solo via UI: bottone admin nascosto via CSS, ma endpoint
/admin/deleteaperto a tutti. Sempre middleware/decorator di autorizzazione sull’endpoint. - Errori troppo dettagliati: “user not found” vs “wrong password” → enumeration attack. Stesso errore generico per entrambi: “credenziali non valide”.
- Sessione senza scadenza o senza revoca: utente logged forever, anche dopo cambio password. Sessione con TTL ragionevole, possibilità di revoca.
Procedura pratica
Per progettare auth in un’app:
- Decidi modello identità: email/password, magic-link, OAuth (Google/Apple/GitHub), passkey, MFA.
- Scegli provider o auth a mano: per quasi tutti i casi, provider (Clerk, Supabase, Auth.js).
- Definisci ruoli/permessi: cominci con 2-3 ruoli, espandi se servono.
- Specifica autorizzazione per endpoint: per ogni endpoint, chi può chiamarlo + quali risorse può toccare.
- Strategia sessione: cookie HttpOnly + scadenza, refresh, logout su tutti dispositivi.
- Test casi negativi: utente non autenticato, autenticato ma non autorizzato, token scaduto, token manipolato.
Laboratorio guidato
Progetta a parole un flusso login/logout + endpoint protetto.
Auth flow (magic-link):
- Utente inserisce email su
/login. - POST
/auth/request-link→ server genera token random firmato, salva con scadenza 15 min, invia email con linkhttps://app/auth/verify?token=.... - Utente clicca link → GET
/auth/verify?token=...→ server verifica firma + scadenza, crea sessione, set cookie HttpOnly Secure SameSite=Lax, redirect a/dashboard. - Da qui in poi, ogni richiesta include cookie sessione, server lo verifica.
- Logout: POST
/auth/logout→ server distrugge sessione lato server + clear cookie.
Endpoint protetto (esempio: cancella ordine):
- DELETE
/orders/:id. - Middleware autenticazione: verifica cookie sessione → se valido, attacca user a request; se no, 401.
- Middleware autorizzazione: legge ordine da DB, verifica
order.user_id === user.id(ownership) ORuser.role === 'admin'. Se no, 403. - Esegui delete.
- Risposta 204 (no content) su successo, 404 se non trovato (mai distinguere 404 da 403 per ridurre information leak).
Casi da gestire:
- Token magic-link già usato → errore “link non valido o scaduto” (stesso messaggio per non rivelare).
- Cookie scaduto → 401 con redirect a login.
- Tentativo di delete ordine altrui → 404 (non 403, per non rivelare esistenza).
Output atteso
Una specifica API per auth + 1 endpoint protetto, con: metodo, URL, request, response, codici errore, regole di autorizzazione. Documento di una pagina, allegato al prompt prima di chiedere implementazione.
Studio passo passo
Studia questa lezione in tre passaggi, senza correre subito al prompt o al codice.
- Prima lettura: chiarisci l’obiettivo: capire i concetti base che regolano accesso e scambio dati, prima di chiedere all’AI di implementarli. Se non riesci a riscriverlo in una frase tua, rileggi il nucleo della lezione.
- Seconda lettura: trasforma i contenuti in domande operative:
- API come contratto tra parti: endpoint, request, response, errori, versionamento implicito.
- Autenticazione come identità, autorizzazione come permesso, sessione come continuità dell’accesso.
- Rischi da non banalizzare: token esposti, controlli solo lato client, ruoli confusi, errori troppo dettagliati.
- Applicazione: svolgi il laboratorio: progettare a parole un flusso login/logout e un endpoint protetto, senza scrivere codice. L’output da ottenere è: una specifica di API essenziale con casi di successo, fallimento e permessi richiesti.
Prima di passare alla lezione successiva, controlla di avere un artefatto concreto: una tabella, un prompt, una checklist, un mini report, un diff commentato o una decisione scritta. Nel vibe coding la comprensione resta astratta finché non produce una traccia verificabile.
Checklist di verifica
- distinguo authentication da authorization;
- so quali cookie flags servono per sessione sicura;
- ho una preferenza chiara fra cookie/sessione vs JWT, con motivazione;
- riconosco i 5 anti-pattern e li evito nei prompt;
- progetto i casi negativi prima dell’happy path.
Errori comuni
Implementare auth a mano da zero. Anche per progetti piccoli, raramente è la scelta giusta. Provider gestiscono dettagli (rate limit, lockout, MFA, password reset).
Non usare HTTPS in produzione. Senza HTTPS, qualsiasi sicurezza auth è teatro. Vercel, Netlify, Fly, Railway: HTTPS automatico. Self-hosting: Caddy, Traefik, Let’s Encrypt.
Verificare ruoli sul client. Rivelano rapidamente fragilità: bypass via DevTools.
Non testare casi negativi. “Login funziona” ≠ “auth è sicura”. Test: token mancante, token scaduto, token manipolato, ownership violata, ruolo insufficiente.
JWT senza refresh strategy. Token long-lived = se rubato, attaccante ha accesso a lungo. Token corto + refresh in cookie HttpOnly.
Prompt di lavoro
Voglio progettare auth + autorizzazione per: [descrizione app + utenti]
Vincoli:
- piattaforma: [web / mobile / entrambe]
- utenti: [scala stimata]
- compliance: [GDPR base / settoriale]
- budget: [con / senza provider esterno]
Aiutami in 4 fasi (rispondi una alla volta, aspetta mio OK):
Fase 1: scelta modello identità (password, magic-link, OAuth, passkey, MFA) con trade-off per il mio caso.
Fase 2: scelta sessione (cookie/sessione server vs JWT vs entrambi) con motivazione.
Fase 3: ruoli e permessi minimi. Tabella ruolo → permessi, con esempi su endpoint principali.
Fase 4: flusso login/logout completo + 2 endpoint protetti (uno con check ownership, uno con check ruolo). Specifica request/response/errori/casi negativi. NO codice ancora.
Concludi con anti-pattern da evitare specifici alla mia scelta.
Esercizio finale
Apri devtools di un’app che usi (la tua o di terze parti rispettando ToS). Cerca: dove è salvato il token? Cookie HttpOnly o localStorage? Quali flags ha il cookie? Cosa succede se cancelli il cookie e provi a chiamare l’API protetta? L’esercizio non è hacking: è osservazione. Vedi pattern reali, riconosci buone e cattive pratiche, calibri il tuo prompt per ottenere la prima e non la seconda.