Vai al contenuto principale

Captive Portal personalizzato: Guida HTML e CSS

Questa guida di riferimento tecnico autorevole delinea gli standard di sviluppo, l'architettura CSS e i vincoli a livello di rete necessari per progettare e codificare una pagina di destinazione Captive Portal personalizzata. Offre agli sviluppatori frontend e agli architetti di rete strategie attuabili per navigare negli ambienti Apple CNA e webview Android, garantendo esperienze WiFi per gli ospiti precise al pixel, conformi e ad altissime prestazioni.

Di Tom HackettPubblicato Aggiornato
📖 11 minuti di lettura3,821 parole2 esempi pratici3 domande di esercitazione8 definizioni chiave

Video overview

Ascolta questa guida

Visualizza trascrizione del podcast
Captive Portal personalizzato: Guida HTML e CSS - Un Briefing Tecnico Purple [INTRODUCTION] Benvenuto nella serie di Briefing Tecnici Purple. Oggi scenderemo nei dettagli di un aspetto che interessa ogni singolo deployment di WiFi per ospiti: il Captive Portal. Nello specifico, parleremo di come scrivere codice HTML e CSS pulito e affidabile per una landing page personalizzata di un Captive Portal. Se ti è mai capitato di connetterti al WiFi di un hotel e di trovarti di fronte a una splash page non funzionante - immagini mancanti, testo privo di stile, un pulsante di accesso che non risponde al tocco - hai sperimentato ciò che accade quando uno sviluppatore crea un portale senza comprendere i vincoli dell'ambiente in cui viene eseguito. Oggi faremo in modo che questo non accada a te. Questo briefing si rivolge a sviluppatori frontend, designer creativi e sviluppatori web che stanno creando un Captive Portal da zero o personalizzando un modello esistente. Tratteremo la struttura HTML, le regole CSS fondamentali, i vincoli del mini-browser Apple CNA che mettono in difficoltà anche gli sviluppatori più esperti, e come le piattaforme come il portal builder di Purple possano eliminare del tutto la maggior parte di questa complessità. Entriamo nel vivo dell'argomento. [TECHNICAL DEEP-DIVE] Per prima cosa, stabiliamo cos'è effettivamente un Captive Portal a livello di rete. Quando un dispositivo si connette a una rete WiFi che richiede l'autenticazione, la rete intercetta il traffico HTTP e reindirizza l'utente a una landing page. Questo è il Captive Portal. L'utente visualizza una splash page, completa un'azione - inserire un'e-mail, accettare i termini, accedere tramite social - e la rete concede quindi l'accesso completo a Internet. L'aspetto cruciale da comprendere è il luogo in cui questa pagina viene visualizzata. Sui dispositivi iOS, si apre all'interno del Captive Network Assistant di Apple - il CNA - che è una webview WebKit ridotta all'essenziale. Non è Safari. Non ha cookie persistenti. Non può caricare risorse esterne. Ha un supporto JavaScript limitato. E si chiude nel momento in cui l'utente passa a un'altra app. Su macOS, il CNA viene visualizzato a una risoluzione fissa di 900 per 572 pixel. Su Android, i dispositivi moderni utilizzano i Chrome Custom Tabs, che sono notevolmente più performanti. Windows 10 apre il browser predefinito dell'utente. I dispositivi Samsung utilizzano Samsung Internet. Questa frammentazione delle piattaforme è la principale causa di malfunzionamento dei Captive Portal in produzione. Gli sviluppatori effettuano i test sul proprio telefono Android, tutto sembra perfetto, e poi gli ospiti dell'hotel dotati di iPhone visualizzano una schermata bianca con testo privo di stile. Parliamo quindi di come scrivere codice in modo preventivo. La regola d'oro per l'HTML e il CSS dei Captive Portal è questa: tratta la pagina come se non avesse una connessione a Internet. Perché, durante la fase di autenticazione, effettivamente non ce l'ha. La rete è prigioniera. Qualsiasi risorsa che la tua pagina tenta di caricare da un URL esterno - un Google Font, un foglio di stile ospitato su CDN, una libreria JavaScript, l'immagine di un logo - fallirà silenziosamente o causerà un indicatore di caricamento infinito.Iniziamo con la struttura HTML. Il documento deve essere una pagina HTML5 pulita. Nell'head, è necessario un meta tag viewport con content impostato su width equals device-width e initial-scale equals one. Questo non è negoziabile per il rendering da mobile. Senza di esso, iOS visualizzerà la pagina con una larghezza di 980 pixel e la ridurrà, rendendo tutto microscopico. Il CSS deve essere inline - all'interno di un blocco style nell'elemento head, o come attributi style inline sui singoli elementi. Non utilizzare un foglio di stile esterno collegato tramite un tag link. Quel foglio di stile risiede sul tuo server, che la rete del Captive Portal non può raggiungere durante l'autenticazione. La pagina verrebbe visualizzata completamente priva di stile. Per i font, utilizza uno stack di font di sistema. Qualcosa come: font-family - apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif. Questo indica al browser di utilizzare qualsiasi font di sistema sia disponibile. Non utilizzare Google Fonts. La chiamata di importazione fallirà e il font di fallback sarà il Times New Roman, che non è l'esperienza di brand per cui il cliente sta pagando. Per le immagini - il logo, la grafica di sfondo, gli elementi decorativi - hai due opzioni. Puoi ospitarle sullo stesso server del Captive Portal, il che significa che si trovano sulla stessa rete locale e sono accessibili prima del completamento dell'autenticazione. Oppure, scelta consigliata, codificale come URI di dati Base64 direttamente nel tuo HTML o CSS. Questo elimina completamente la dipendenza esterna. Parliamo ora del layout della pagina. Poiché oltre il novanta percento degli accessi al Captive Portal avviene su dispositivi mobili, il design deve essere mobile-first. Ciò significa un layout a colonna singola, una larghezza massima di circa 480 pixel, centrato sulla pagina. Usa flexbox sull'elemento body - display flex, flex-direction column, align-items centre, justify-content centre, min-height 100 viewport height. Questo centra la scheda dei contenuti verticalmente e orizzontalmente su qualsiasi dimensione dello schermo. Il pulsante principale di chiamata all'azione (CTA) deve essere ottimizzato per il tocco. Le linee guida per l'interfaccia umana di Apple specificano un'area minima di tocco di 44 per 44 pixel. In pratica, per una CTA principale, è preferibile un'altezza di circa 48 pixel, a larghezza intera all'interno del contenitore, con un raggio del bordo di circa 8-12 pixel. Per i campi del modulo - inserimento dell'e-mail, inserimento del nome - imposta la dimensione del font ad almeno 16 pixel. Questo aspetto è fondamentale. iOS Safari e il CNA ingrandiranno automaticamente qualsiasi campo di inserimento con una dimensione del font inferiore a 16 pixel, interrompendo il layout curato con attenzione. L'impostazione del font a 16 pixel o superiore impedisce questo comportamento di zoom. La sezione sul consenso legale merita una particolare attenzione. Ai sensi del GDPR, se raccogli dati personali - anche solo un indirizzo e-mail - hai bisogno di un consenso esplicito e informato. Ciò significa una casella di controllo deselezionata per impostazione predefinita, con un'etichetta visibile che indica chiaramente a cosa l'utente sta acconsentendo. Non preselezionare la casella di controllo. La casella di controllo del consenso stessa deve essere chiaramente visibile senza scorrere la pagina. Ora, un dettaglio di implementazione cruciale specifico per il CNA di iOS. Quando l'utente completa l'autenticazione, il CNA monitora se il dominio captive è diventato accessibile. Il controllo viene attivato dalla navigazione a pagina intera, non dalle chiamate AJAX JavaScript. Ciò significa che se si crea una single-page app che invia il modulo tramite fetch o XMLHttpRequest e aggiorna il DOM senza un reindirizzamento completo della pagina, il CNA non rileverà mai che l'autenticazione è stata completata. È necessario reindirizzare a un nuovo URL dopo l'autenticazione - un reindirizzamento HTTP completo, non una manipolazione del DOM JavaScript. Questo è uno degli errori più comuni nello sviluppo di un Captive Portal. Per JavaScript, riducilo al minimo. Il CNA ha un supporto JS limitato e nessun accesso a localStorage o sessionStorage. I cookie vengono distrutti alla chiusura del CNA. Qualsiasi gestione dello stato che si affida a queste API del browser fallirà. I listener di eventi vanilla JavaScript vanno bene. jQuery è una dipendenza esterna da 30 kilobyte che non riuscirà a caricarsi. [RACCOMANDAZIONI DI IMPLEMENTAZIONE E TRAPPOLE DA EVITARE] Ecco la checklist pratica per l'implementazione. Primo: tag meta viewport, sempre. Secondo: tutto il CSS in linea, nessun foglio di stile esterno. Terzo: tutte le immagini servite dal server del Captive Portal o codificate in Base64. Quarto: stack di font di sistema, nessun web font. Quinto: dimensione minima del carattere di 16 pixel su tutti i campi di input. Sesto: target di tocco ottimizzati per il touch, minimo 44 per 44 pixel. Settimo: layout a colonna singola, larghezza massima 480 pixel. Ottavo: reindirizzamento a pagina intera al momento dell'autenticazione, non un aggiornamento dello stato JavaScript. Nono: casella di controllo del consenso conforme al GDPR, deselezionata per impostazione predefinita. Decimo: test su un dispositivo iOS reale utilizzando una rete captive effettiva, non un'anteprima del browser. Le trappole che vedo più spesso in produzione. Numero uno: Google Fonts - rimuovi l'importazione, fallirà. Numero due: librerie JavaScript esterne - Bootstrap, jQuery, qualsiasi script ospitato su CDN fallirà. Numero tre: variabili CSS dichiarate in un foglio di stile esterno - devono trovarsi nel blocco di stile in linea. Numero quattro: immagini di sfondo richiamate tramite URL - codificale in Base64. Numero cinque: invio del modulo AJAX senza un reindirizzamento post-autenticazione - il CNA non rileverà il completamento dell'autenticazione. Ora, un discorso onesto sulla scelta tra build o buy. Creare un Captive Portal personalizzato da zero significa essere responsabili anche dell'infrastruttura backend - il server RADIUS, il database, il certificato SSL, la configurazione DNS, l'integrazione di rete con i punti di accesso e l'applicazione continua di patch di sicurezza. Si tratta di un impegno ingegneristico significativo. Il costruttore di portali di Purple offre un'interfaccia drag-and-drop con un editor HTML e CSS personalizzato per gli sviluppatori che necessitano di un controllo pixel-perfect, gestendo al contempo tutta l'infrastruttura backend - l'autenticazione, la cattura dei dati, l'analitica, gli strumenti di conformità al GDPR e le integrazioni di rete con oltre 200 fornitori di punti di accesso. Si ottiene il controllo creativo senza il sovraccarico dell'infrastruttura. [DOMANDE E RISPOSTE RAPIDE] Posso usare CSS Grid in un captive portal? Sì, ma testa specificamente su iOS CNA. Flexbox ha un supporto più ampio nelle versioni più vecchie di WebKit. Posso usare loghi SVG? Sì, gli SVG inline sono completamente supportati e preferibili ai PNG codificati in Base64 per i loghi perché si ridimensionano perfettamente sui display retina. Il CNA di macOS supporta gli stessi vincoli del CNA di iOS? In generale sì, con una differenza: il CNA di macOS viene renderizzato in una finestra fissa di 900 per 572 pixel. Posso usare un framework CSS come Tailwind? Solo se generi un file CSS ripulito e autonomo e lo inserisci inline nel tuo blocco di stile. E per quanto riguarda l'HTTPS? Il tuo captive portal deve essere servito tramite HTTP affinché il reindirizzamento iniziale funzioni - le connessioni HTTPS non possono essere intercettate dalla rete captive. [RIASSUNTO E PROSSIMI PASSI] Per riassumere il briefing di oggi. Un captive portal personalizzato è un ambiente web limitato, non un normale contesto browser. L'Apple CNA e i webview Android impongono rigide limitazioni alle risorse esterne, ai cookie, a JavaScript e allo stato della sessione. La soluzione consiste nel creare pagine HTML autonome con CSS inline, font di sistema, immagini codificate in Base64 e reindirizzamenti a pagina intera al momento dell'autenticazione. Per i gestori delle sedi e i team IT che stanno valutando le proprie opzioni: se il vostro requisito è un portale completamente personalizzato con HTML e CSS personalizzati, la scelta è tra creare e mantenere l'intero stack da soli - il che rappresenta un impegno ingegneristico notevole - o utilizzare una piattaforma come Purple che fornisce funzionalità di modifica di HTML e CSS personalizzati sopra un'infrastruttura backend di livello enterprise. I prossimi passi da qui: consulta la documentazione dell'editor del portale di Purple, verifica il tuo portale esistente rispetto alla checklist mobile-first che abbiamo trattato oggi e, se stai partendo da zero, utilizza la struttura del modello HTML che abbiamo delineato come base di partenza. Grazie per l'ascolto e ci vediamo al prossimo briefing.

Parte della nostra serie principale: Guida al Captive Portal →

Captive Portal personalizzato: Guida HTML e CSS

Executive Summary

Per le sedi aziendali - che spaziano dagli hotel di lusso Hospitality e catene di negozi Retail agli hub di transito Transport e moderni campus medici Healthcare - la pagina di benvenuto del WiFi per gli ospiti rappresenta la porta d'ingresso digitale. Tuttavia, oltre il 90% degli accessi al WiFi per gli ospiti avviene su dispositivi mobili, dove la visualizzazione non è gestita da browser standard come Safari o Chrome, ma da webview Captive Network Assistant (CNA) altamente limitate [1]. Questi "mini-browser" impongono severe limitazioni di sandbox: bloccano i CDN esterni, disabilitano i cookie persistenti, ignorano i web font esterni e limitano fortemente l'esecuzione di JavaScript per ridurre i rischi di sicurezza e prevenire il dirottamento delle sessioni [2].

Quando uno sviluppatore progetta una pagina di benvenuto utilizzando gli standard web tradizionali, questi vincoli si traducono in layout interrotti, elementi del brand mancanti e pulsanti di accesso non funzionanti, influenzando direttamente la soddisfazione dei clienti e l'interazione digitale. Questa guida fornisce soluzioni a queste sfide, presentando pratiche di codifica difensive - come CSS inline, codifica degli asset in Base64, stack di font di sistema e handshake di autenticazione espliciti basati sulla navigazione - per garantire una visualizzazione multipiattaforma fluida. Inoltre, esaminiamo come l'utilizzo di una soluzione gestita come il builder di portali di Purple consenta agli sviluppatori di mantenere il controllo creativo completo su HTML/CSS delegando l'autenticazione RADIUS, la scalabilità del database, la conformità GDPR/PCI e le integrazioni AP multi-vendor [3].

Approfondimento Tecnico

Per creare un Captive Portal personalizzato e resiliente, gli sviluppatori devono comprendere l'intercettazione a livello di rete e la virtualizzazione del browser che si verificano quando un ospite si associa a un Service Set Identifier (SSID) aperto.

Il Ciclo di Vita del Captive Portal

Quando un dispositivo client si associa a un SSID captive, si attiva la seguente sequenza:

  1. Associazione IP: Il dispositivo completa un handshake a 3 vie e richiede un indirizzo IP tramite DHCP.
  2. Sonda di Connettività Attiva: Il gestore di rete in background del sistema operativo invia immediatamente una richiesta HTTP GET a un URL canary dedicato e neutrale rispetto al fornitore (ad es., http://captive.apple.com/hotspot-detect.html di Apple o http://connectivitycheck.gstatic.com/generate_204 di Google) [1].
  3. Intercettazione DNS/HTTP: Il Wireless LAN Controller (WLC) o l'Access Point (AP) locale intercetta questa richiesta HTTP sulla porta 80. Invece di restituire lo stato HTTP 200 o 204 previsto, il gateway reindirizza il traffico del client all'URL della pagina di destinazione del Captive Portal tramite un reindirizzamento HTTP 302 [2].
  4. Generazione della Webview: Rilevando il reindirizzamento, il sistema operativo avvia il proprio mini-browser Captive Network Assistant (CNA) nativo per visualizzare la pagina di benvenuto reindirizzata, evitando che l'utente debba aprire manualmente un browser completo.5. Autenticazione e transizione di stato: l'utente compila il modulo di login, inviando le credenziali al server del portale, che istruisce il gateway (spesso tramite un Access-Accept RADIUS o una chiamata API esterna) ad autorizzare l'indirizzo MAC.
  5. Handshake di uscita CNA: il mini-browser CNA esegue un altro HTTP GET verso il suo URL canary. Se riceve la risposta 200/204 prevista, cambia il pulsante in alto a destra da "Annulla" a "Fine" e stabilisce la connessione WiFi come interfaccia di rete primaria.

Vincoli del mini-browser specifici per piattaforma

Ogni sistema operativo gestisce questo ciclo di vita all'interno di diversi ambienti webview, con conseguente comportamento altamente frammentato. La tabella seguente illustra in dettaglio questi vincoli critici:

Piattaforma / Webview Metodo di visualizzazione Cookie persistenti Font web esterni Esecuzione JavaScript Dimensioni della finestra Trigger dell'handshake di uscita
Apple iOS CNA (Websheet) Popup del mini-browser Bloccati (Distrutti alla chiusura) Bloccati (Offline) Limitata (No localStorage/sessionStorage) Reattiva (Larghezza del dispositivo) Solo reindirizzamento HTTP a pagina intera [1]
Apple macOS CNA (Captive Network Assistant) Popup del mini-browser Bloccati Bloccati Limitata (No finestre di dialogo alert/confirm) Fissa (900px x 572px) Solo reindirizzamento HTTP a pagina intera
Android (Google) (CaptivePortalLogin) Notifica push -> Scheda personalizzata Chrome Consentiti (Condivisi con Chrome) Consentiti (Se inclusi nella whitelist del walled garden) Completa Reattiva Automatico (API Captive Portal / Controllo 204) [2]
Samsung Android (Samsung Internet) Notifica push -> Mini-browser Consentiti Consentiti Completa Reattiva Automatico
Windows 10/11 (Browser predefinito) Avvio automatico del browser predefinito Consentiti (Contesto completo del browser) Consentiti Completa Reattiva Manuale / Automatico

Captive Portal personalizzato: Guida HTML e CSS - cna constraints comparison

Aggirare la trappola del pulsante "Fine" su Apple CNA

Uno dei problemi di funzionamento più frequenti nello sviluppo di Captive Portal personalizzati è la trappola del pulsante "Fine" sui dispositivi iOS. Quando un utente esegue l'autenticazione, la webview dell'iOS Websheet deve rilevare che la rete non è più captive. Per farlo, monitora il successo delle sue richieste canary in background.

Fondamentalmente, il CNA di iOS attiverà questo controllo solo a seguito di una navigazione HTTP a pagina intera (reindirizzamento della posizione). Se uno sviluppatore crea una moderna Single Page Application (SPA) che invia i dati del modulo tramite una chiamata AJAX asincrona (ad es. fetch() o Axios) e aggiorna il DOM in modo dinamico senza modificare l'URL, il CNA non eseguirà mai una seconda volta il suo controllo di connettività. L'utente verrà autenticato a livello di gateway, ma il pulsante del CNA nell'angolo in alto a destra rimarrà impostato su "Annulla". Se l'utente frustrato fa clic su "Annulla", il dispositivo iOS si disassocerà immediatamente dall'SSID, interrompendo la sessione WiFi [1].

Per evitare questo problema, il gestore del successo dell'autenticazione deve eseguire un reindirizzamento a pagina intera verso una pagina di destinazione fisica (ad es. window.location.href = '/success') o inviare il modulo di accesso in modo nativo tramite una richiesta standard HTTP POST.

Guida all'implementazione

Per garantire un rendering coerente su tutte le piattaforme, gli sviluppatori devono passare dal design web moderno e ricco di risorse a uno stile di codifica altamente autonomo e difensivo.

La regola d'oro: Progettare per una connettività Internet pari a zero

Durante lo stato captive, il dispositivo client non ha alcun accesso a Internet. Può solo risolvere e accedere a indirizzi IP e domini esplicitamente inclusi nella whitelist del controller wireless denominata Walled Garden (come l'IP del server del Captive Portal stesso). Pertanto, qualsiasi risorsa esterna a cui si fa riferimento nel codice HTML non verrà caricata, compromettendo il layout.

Per progettare in modo difensivo, implementa la seguente Lista di controllo per la progettazione del Captive Portal Mobile-First:

Captive Portal personalizzato: Guida HTML e CSS - mobile first checklist

1. Configurazione del Viewport

Per evitare che i dispositivi mobili riducano il viewport a una larghezza desktop (in genere 980px), l'HTML <head> deve includere un meta tag responsive per il viewport. Senza di questo, il testo e i campi di input appariranno microscopici sui dispositivi mobili:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

2. Incorporamento di CSS in linea ed eliminazione delle dipendenze esterne

Non collegare mai file CSS esterni o CDN (ad es. Bootstrap, Tailwind o Google Fonts). Tutto il codice CSS deve essere inserito all'interno di un blocco <style> nell' <head> dell'HTML.

Per la tipografia, utilizza un system font stack che fa riferimento ai caratteri locali preinstallati nel sistema operativo. In questo modo si evitano del tutto le richieste HTTP e si garantisce che la pagina si carichi istantaneamente utilizzando il carattere sans-serif nativo e di alta qualità del dispositivo:

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background-color: #F5F1ED; /* Pearl White Brand Colour */
    color: #011638; /* Dark Blue Brand Colour */
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
}

3. Codifica degli Asset in Base64

Le immagini, i loghi e le icone non devono essere richiamati tramite URL HTTP esterni, a meno che il dominio ospitante non sia inserito nella whitelist del walled garden del gateway. Il metodo più affidabile consiste nel codificare i piccoli elementi visivi (come i loghi PNG o SVG) direttamente all'interno dell'HTML o del CSS come URI di dati Base64:

<!-- Inline Base64 Logo Example -->
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iIzc0NThGRCIvPjwvc3ZnPg==" alt="Purple Logo" class="brand-logo">

4. Ottimizzazione dei Campi di Input e dei Target di Selezione (Tap)

Per garantire la conformità con gli standard di usabilità su dispositivi mobili (come le linee guida sull'interfaccia umana di Apple), tutti gli elementi interattivi devono essere ottimizzati per l'input tattile:

  • Dimensione del Font di Input: Le dimensioni del carattere del testo di input devono essere di almeno 16px. Se la dimensione del font è inferiore (ad es. 14px), iOS Safari e il CNA ingrandiranno automaticamente il campo di input al momento della messa a fuoco, distorcendo il layout della pagina [1].
  • Target di Selezione: Pulsanti, caselle di controllo e collegamenti devono avere un'area minima del target di selezione pari a 44px x 44px per evitare clic accidentali o frustrazione da parte dell'utente.

5. Consenso Legale e Conformità GDPR

Durante l'acquisizione dei dati degli ospiti (ad es. e-mail, numero di telefono o profili social), la struttura HTML deve supportare un consenso legale esplicito. Ai sensi del GDPR, le caselle di controllo preselezionate o le dichiarazioni di consenso implicite (ad es. "Accedendo, accetti i nostri termini") non sono conformi [3].

  • Fornire una casella di controllo non selezionata per impostazione predefinita per i Termini e Condizioni e l'Informativa sulla Privacy.
  • Inserire il testo legale dettagliato in un contenitore ad altezza limitata con barra di scorrimento (max-height: 120px; overflow-y: auto;) per mantenere il modulo di login principale sopra la piega della pagina (above the fold).
<div class="consent-container">
    <input type="checkbox" id="terms_consent" name="terms_consent" required>
    <label for="terms_consent">
        I explicitly agree to the <a href="#" onclick="showTerms()">Terms of Service</a> and consent to the processing of my data in accordance with the <a href="#" onclick="showPrivacy()">Privacy Policy</a>.
    </label>
</div>

Hai domande sulla tua configurazione specifica?

Il nostro team collabora con gestori di sedi, responsabili IT e ingegneri di rete in 80.000 sedi. Prenota una chiamata di 20 minuti e ti mostreremo come altri professionisti come te hanno risolto il problema.

Modello HTML/CSS Personalizzato per Captive Portal

Di seguito è riportato un modello HTML/CSS a file singolo, completo e pronto per la produzione, che integra tutte le migliori pratiche ottimizzate per dispositivi mobili e conformi al CNA. Presenta un layout responsive, un set di caratteri di sistema, segnaposto per asset pronti per Base64, campi di input touch-friendly e strutture di consenso esplicito conformi al GDPR:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Guest WiFi Login</title>
    <style>
        /* CSS Reset & Variable Declarations */
        :root {
            --color-primary: #7458FD; /* Purple Brand Colour */
            --color-dark: #011638; /* Dark Blue */
            --color-light: #F5F1ED; /* Pearl White */
            --color-white: #FFFFFF;
"}            --color-border: #D1D5DB;
            --radius-container: 12px;
            --radius-element: 6px;
        }
        
        * {
            box-sizing: border-box;
            -webkit-tap-highlight-color: transparent;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
            background-color: var(--color-light);
            color: var(--color-dark);
            margin: 0;
            padding: 20px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
        }
        
        /* Layout scheda reattiva */
        .portal-card {
            background-color: var(--color-white);
            width: 100%;
            max-width: 420px;
            padding: 32px 24px;
            border-radius: var(--radius-container);
            box-shadow: 0 4px 20px rgba(1, 22, 56, 0.05);
            text-align: center;
        }
        
        .logo-container {
            margin-bottom: 24px;
        }
        
        /* Segnaposto logo incorporato in Base64 */
        .logo {
            width: 120px;
            height: auto;
        }
        
        h1 {
            font-size: 24px;
            font-weight: 700;
            margin: 0 0 8px 0;
            color: var(--color-dark);
        }
        
        p {
            font-size: 14px;
            color: #4B5563;
            margin: 0 0 24px 0;
            line-height: 1.5;
        }
        
        /* Stili modulo */
        .form-group {
            text-align: left;
            margin-bottom: 16px;
        }
        
        label {
            display: block;
            font-size: 14px;
            font-weight: 600;
            margin-bottom: 6px;
            color: var(--color-dark);
        }
        
        /* Critico: la dimensione del carattere deve essere di almeno 16px per impedire lo zoom automatico in iOS */
        input[type="email"],
        input[type="text"] {
            width: 100%;
            height: 48px;
            padding: 12px 16px;
            font-size: 16px;
            border: 1px solid var(--color-border);
            border-radius: var(--radius-element);
            background-color: var(--color-white);
            color: var(--color-dark);
            outline: none;
            transition: border-color 0.2s;
        }
        
        input[type="email"]:focus,
        input[type="text"]:focus {
            border-color: var(--color-primary);
            box-shadow: 0 0 0 3px rgba(116, 88, 253, 0.15);
        }
        
        /* Stili consenso */
        .consent-group {
            display: flex;
            align-items: flex-start;
            text-align: left;
            margin: 20px 0;
        }
        
        /* Dimensionamento del target ottimizzato per il touch */
        input[type="checkbox"] {
            width: 20px;
            height: 20px;
            margin: 2px 12px 0 0;
            flex-shrink: 0;
            cursor: pointer;
            accent-color: var(--color-primary);
        }
        
        .consent-label {
            font-size: 13px;
            line-height: 1.4;
            color: #4B5563;
            user-select: none;
        }
        
        .consent-label a {
            color: var(--color-primary);
            text-decoration: none;
            font-weight: 600;
        }
        
        .consent-label a:hover {
            text-decoration: underline;
        }
        
        /* Touch-Friendly CTA Button (Minimum 44px height) */
        .btn-submit {
            width: 100%;
            height: 48px;
            background-color: var(--color-primary);
            color: var(--color-white);
            border: none;
            border-radius: var(--radius-element);
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: background-color 0.2s;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        .btn-submit:hover {
            background-color: #5B3EE3;
        }
        
        .btn-submit:active {
            background-color: #4A2FD4;
        }
        
        /* Legal Terms Scrollbox */
        .terms-scrollbox {
            display: none; /* Toggled via JS */
            text-align: left;
            font-size: 11px;
            color: #6B7280;
            background-color: var(--color-light);
            padding: 12px;
            border-radius: var(--radius-element);
            max-height: 100px;
            overflow-y: auto;
            margin-bottom: 16px;
            border: 1px solid var(--color-border);
        }
        
        .footer {
            margin-top: 24px;
            font-size: 11px;
            color: #9CA3AF;
        }
    </style>
</head>
<body>

    <div class="portal-card">
        <div class="logo-container">
            <!-- Replace src with your actual Base64-encoded SVG or PNG -->
            <svg class="logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 30">
                <rect width="100" height="30" rx="6" fill="#7458FD"/>
                <text x="50" y="20" font-family="sans-serif" font-size="12" fill="#FFFFFF" font-weight="bold" text-anchor="middle">IL TUO BRAND</text>
            </svg>
        </div>
        
        <h1>Benvenuto nel WiFi per gli ospiti</h1>
        <p>Inserisci i tuoi dati qui sotto per accedere a internet in modo sicuro e ad alta velocità.</p>
        
        <!-- Form must submit natively (full page navigation) to clear Apple CNA -->
        <form action="/login/submit" method="POST" onsubmit="return validateForm()">
            <div class="form-group">
                <label for="guest_name">Nome e Cognome</label>
                <input type="text" id="guest_name" name="name" placeholder="Mario Rossi" required autocomplete="name">
            </div>
            
            <div class="form-group">
                <label for="guest_email">Indirizzo e-mail</label>
                <input type="email" id="guest_email" name="email" placeholder="john@example.com" required autocomplete="email">
            </div>
            
            <div class="consent-group">
                <input type="checkbox" id="terms_consent" name="terms_accepted" required>
                <label for="terms_consent" class="consent-label">
                    Accetto i <a href="#" onclick="toggleTerms(event)">Termini di Servizio</a> e acconsento al trattamento dei dati in conformità con le normative GDPR.
                </label>
            </div>
            
            <div id="terms_box" class="terms-scrollbox">
                <strong>Termini di Servizio WiFi:</strong><br>
                1. Questo servizio viene fornito così com'è senza garanzie.<br>
                2. Gli utenti non devono intraprendere attività illegali ad alta intensità di banda.<br>
                3. I dati personali vengono raccolti esclusivamente per l'autenticazione e il consenso al marketing in conformità con la nostra Informativa sulla Privacy.
            </div>
            
            <button type="submit" class="btn-submit">Connettiti al WiFi</button>
        </form>
        
        <div class="footer">
            Powered by Purple | Secure Guest WiFi
        </div>
    </div>

    <script>
        function toggleTerms(e) {
            e.preventDefault();
            var box = document.getElementById('terms_box');
            box.style.display = (box.style.display === 'block') ? 'none' : 'block';
        }
        
        function validateForm() {
            var consent = document.getElementById('terms_consent');
            if (!consent.checked) {
                alert('È necessario accettare i Termini di Servizio per connettersi.');
                return false;
            }
            return true;
        }
    </script>
</body>
</html>

Risoluzione dei problemi e mitigazione dei rischi

Durante l'implementazione di Captive Portal HTML/CSS con codice personalizzato, i team di gestione IT incontrano frequentemente diversi gravi rischi operativi:

1. Il loop di avviso del certificato SSL/TLS

Poiché i Captive Portal funzionano intercettando il traffico, presentano un conflitto fondamentale con la moderna sicurezza web HTTPS. Quando un utente tenta di visitare un sito HTTPS (ad es. https://www.google.com) e il gateway tenta di reindirizzare quel traffico verso un Captive Portal HTTP, il browser rileva una mancata corrispondenza nel certificato SSL e mostra un avviso di sicurezza critico "La tua connessione non è privata".

  • Mitigazione: Non tentare mai di intercettare direttamente il traffico HTTPS. Affidarsi interamente all'assistente CNA nativo del sistema operativo (che effettua una richiesta HTTP non crittografata per attivare il reindirizzamento). Assicurarsi che il dominio del Captive Portal disponga di un certificato SSL valido e pubblicamente attendibile (ad es. Let's Encrypt o DigiCert) e che sia servito tramite HTTPS solo dopo che il reindirizzamento HTTP iniziale ha indirizzato con successo l'utente al dominio del portale [2].

2. Errori di risoluzione DNS (la trappola del Walled Garden)

Se la tua pagina HTML personalizzata fa riferimento a risorse esterne - come un endpoint OAuth per l'accesso social (ad es. Facebook, Google) o un gateway di pagamento - le richieste DNS per questi domini falliranno a meno che non siano esplicitamente inserite nella whitelist del Walled Garden del controller wireless. Se un dominio manca dalla whitelist, il flusso di accesso si bloccherà, presentando una schermata vuota.

  • Mitigazione: Mantieni un elenco di Walled Garden rigoroso e ridotto al minimo. Se utilizzi i social login, inserisci nella whitelist i domini wildcard specifici consigliati dagli identity provider (ad es. *.google.com, *.gstatic.com).

3. Timeout della sessione e vulnerabilità di spoofing MAC

I Captive Portal standard autenticano i dispositivi in base ai loro indirizzi MAC. Tuttavia, i moderni sistemi operativi mobili (iOS 14+ e Android 10+) utilizzano per impostazione predefinita indirizzi MAC casuali (indirizzi WiFi privati), ruotandoli periodicamente. Ciò può far sì che agli ospiti venga ripetutamente richiesto di ripetere l'autenticazione, compromettendo l'esperienza utente [1].

  • Mitigazione: Implementa timeout di sessione ragionevoli (ad es. 24 ore) sul server RADIUS per prevenire sessioni non aggiornate e utilizza standard di autenticazione moderni come Passpoint (Hotspot 2.0) o WPA3-Enterprise per un onboarding fluido e sicuro che bypassi completamente i Captive Portal basati su MAC.

Rilevanza dei prodotti Purple: Build vs. Buy

Sebbene la codifica di una singola pagina HTML sia semplice, ospitare, proteggere e scalare un'infrastruttura di Captive Portal personalizzata presenta enormi ostacoli tecnici e di conformità. La tabella seguente confronta le realtà ingegneristiche e operative dell'hosting autonomo di un portale personalizzato rispetto all'utilizzo della piattaforma aziendale gestita di Purple:

Caratteristica / Requisito operativo Portale personalizzato self-hosted Piattaforma Purple Enterprise WiFi
Personalizzazione HTML/CSS Codifica completamente manuale, caricamento di file su singoli AP o server web locali. Editor per sviluppatori pixel-perfect che consente l'inserimento di HTML/CSS personalizzati, combinato con un costruttore visivo drag-and-drop.
Infrastruttura RADIUS È necessario distribuire, configurare e mantenere server FreeRADIUS o Cloud RADIUS altamente disponibili [4]. RADIUS nativo del cloud, integrato e distribuito a livello globale con ridondanza active-active e SLA di uptime del 99.99%.
Supporto AP multi-vendor Script di integrazione personalizzati richiesti per ciascun fornitore di hardware (Cisco, Aruba, Meraki, Ruckus) [5]. Integrazione nativa e immediata con oltre 200 modelli di hardware; implementazione unificata del portale su parchi macchine con hardware misto.
Privacy dei dati e conformità La sede si assume il 100% della responsabilità legale per la conformità a GDPR, CCPA e PCI-DSS, inclusi crittografia sicura del database e flussi di lavoro di cancellazione dei dati. Completamente conforme fin dalla progettazione. Gestione del consenso integrata, richieste di cancellazione automatizzate dei soggetti interessati e hosting sicuro certificato ISO 27001.
Analytics & Marketing Richiede la creazione di pipeline di inserimento dati personalizzate e l'integrazione di strumenti di marketing di terze parti. Dashboard di analisi di livello enterprise con monitoraggio delle presenze in tempo reale, metriche sui tassi di ritorno e trigger per campagne di marketing automatizzate [6].
Integrazioni con Identity Provider Integrazioni manuali OAuth2 con Google, Facebook, Apple e gateway SMS locali. Integrazioni con un clic con le principali piattaforme social, gateway SMS e Azure AD / Okta per gli ospiti aziendali.

La piattaforma di Purple risolve il dilemma "Build vs. Buy". Offre agli sviluppatori la completa libertà creativa di uno spazio di lavoro HTML/CSS personalizzato, eliminando al contempo la complessa e rischiosa ingegneria dell'infrastruttura backend necessaria per supportare l'autenticazione RADIUS sicura su scala.

ROI e impatto sul business

Investire in un Captive Portal personalizzato, reattivo e progettato in modo professionale offre ritorni quantificabili in tutte le operazioni IT, nel marketing e nella conformità legale.

1. Riduzione dei costi operativi (ticket dell'helpdesk IT)

Nelle installazioni su larga scala, come uno stadio o una catena di negozi multi-sito, un Captive Portal non funzionante è una delle cause principali dell'aumento dei ticket di assistenza IT. Quando gli ospiti riscontrano una "schermata bianca" o un pulsante di accesso che non risponde, sovraccaricano il personale in loco o inviano ticket di supporto.

$$\text{Risparmio annuale sull'assistenza} = (\text{Visite annuali totali degli ospiti} \times \text{Tasso di errore del portale} \times \text{Tasso di contatto dell'helpdesk}) \times \text{Costo per ticket di supporto}$$

  • Scenario: un centro congressi con 1.000.000 di visitatori all'anno. Un portale codificato male ha un tasso di errore del 5% sui dispositivi iOS più vecchi, il che porta a un tasso di contatto dell'helpdesk del 10%. Con un costo standard del settore di 15 $ per ticket di supporto, il costo operativo è: $$(1.000.000 \times 0.05 \times 0.10) \times $15 = $75.000 \text{ all'anno in costi di supporto evitabili}$$
  • Risultato: il passaggio a un modello ottimizzato per CNA e pensato innanzitutto per i dispositivi mobili riduce il tasso di errore del portale a <0,1%, eliminando virtualmente questo dispendio operativo.

2. Acquisizione dei dati di marketing e ottimizzazione dell'opt-in

Per i punti vendita al dettaglio e i locali del settore hospitality, il portale WiFi per gli ospiti è il meccanismo principale per acquisire dati dei clienti di prima parte puliti. Un'interfaccia utente progettata male, con testi microscopici o un layout del modulo faticoso, causa elevati tassi di rimbalzo - gli utenti abbandonano del tutto il processo di accesso, con conseguente perdita di opportunità di marketing.

  • Caso di studio (Retail): una catena di vendita al dettaglio nazionale ha implementato un Captive Portal ottimizzato per i dispositivi mobili utilizzando la piattaforma di Purple. Sostituendo un modulo di accesso in più passaggi con un campo di inserimento e-mail singolo (dimensione del carattere: 16px) e un pulsante con target di tocco ottimizzato a 48px, hanno registrato un aumento del 42% delle registrazioni completate e un aumento del 28% delle iscrizioni alla newsletter di marketing nel primo trimestre [6].

3. Mitigazione dei rischi legali e normativi

Ai sensi di GDPR e CCPA, la raccolta di dati non conforme comporta severe sanzioni finanziarie (fino al 4% del fatturato annuo globale ai sensi del GDPR). Affidarsi a caselle di controllo preselezionate o non fornire un'Informativa sulla Privacy chiara e facilmente accessibile sulla splash page espone l'azienda a un'immensa responsabilità legale.

  • ROI di mitigazione: L'implementazione di una casella di controllo del consenso esplicita e non selezionata e l'hosting dei termini all'interno di una casella di scorrimento ottimizzata garantiscono la conformità normativa al 100%, mitigando il rischio di sanzioni normative multimilionarie e proteggendo la reputazione del marchio.

Sintesi dei punti chiave

  • La Sandbox CNA è restrittiva: Il Websheet iOS di Apple e il CNA macOS sono ambienti altamente protetti da sandbox che bloccano risorse esterne, cookie e font web. Tutti gli stili e le risorse devono essere autonomi (CSS inline, immagini Base64, font di sistema) [1].
  • AJAX interrompe l'handshake di uscita di iOS: Per far passare correttamente il dispositivo iOS da "connessione limitata" a "connesso" (cambiando il pulsante in alto a destra da "Annulla" a "Fine"), è necessario attivare un reindirizzamento HTTP a pagina intera. Gli aggiornamenti DOM asincroni lasceranno il dispositivo in un ciclo di captive portal continuo.
  • Il Mobile-First è obbligatorio: Oltre il 90% degli accessi avviene da mobile. Progetta un layout a colonna singola (larghezza massima: 480px), utilizza target di tocco ottimizzati per il mobile (minimo 44px x 44px) e applica una dimensione minima del carattere di 16px su tutti i campi di inserimento testo per impedire lo zoom automatico del browser iOS.
  • I Walled Garden controllano il DNS: Qualsiasi dominio esterno a cui si fa riferimento durante l'accesso (ad esempio, le API di login social) deve essere esplicitamente inserito nella whitelist del walled garden del controller wireless, altrimenti la pagina non si caricherà.
  • Purple elimina la complessità del backend: L'utilizzo del costruttore di portali di Purple offre agli sviluppatori il controllo completo di HTML/CSS tramite un editor personalizzato, scaricando al contempo gli immensi oneri di sicurezza, scalabilità e conformità di RADIUS, integrazioni AP multi-vendor e gestione dei database conforme al GDPR [3].

Riferimenti

-

Ascolta il briefing tecnico

Ascolta un senior solutions architect discutere i vincoli tecnici e le strategie di implementazione per i Captive Portal personalizzati:

Definizioni chiave

Captive Portal

Una pagina web che viene mostrata agli utenti appena connessi a una rete WiFi prima che venga concesso loro un accesso più ampio alle risorse di rete, in genere utilizzata per l'autenticazione, il pagamento o la visualizzazione dei termini di servizio.

I team IT distribuiscono i captive portal a livello di gateway per controllare l'accesso degli ospiti, acquisire i dati degli utenti e garantire la conformità legale.

Captive Network Assistant (CNA)

Un mini-browser protetto e altamente limitato, avviato automaticamente dai sistemi operativi (come Apple iOS e macOS) al rilevamento del reindirizzamento di una rete captive, progettato esclusivamente per facilitare l'autenticazione al portale.

Le visualizzazioni web dei CNA impongono limitazioni severe, tra cui il blocco delle CDN esterne, dei cookie persistenti e dell'archiviazione locale, che spesso compromettono i normali design web.

Walled Garden

Un elenco limitato di indirizzi IP, sottoreti o nomi di dominio a cui un utente ospite non autenticato è autorizzato ad accedere attraverso il gateway prima di completare il processo di accesso al captive portal.

Gli sviluppatori devono assicurarsi che qualsiasi risorsa esterna (come le API di social login o i gateway di pagamento) sia inserita nella whitelist del walled garden per evitare che il flusso di accesso si blocchi.

Codifica Base64

Uno schema di codifica da binario a testo che rappresenta dati binari (come le immagini) come una stringa ASCII, consentendo di incorporare le risorse direttamente all'interno di documenti HTML o CSS.

L'utilizzo della codifica Base64 per loghi e icone elimina le richieste HTTP esterne, garantendo che le risorse vengano visualizzate perfettamente all'interno di ambienti CNA offline.

RADIUS (Remote Authentication Dial-In User Service)

Un protocollo di rete che fornisce la gestione centralizzata di autenticazione, autorizzazione e tracciamento (AAA - Authentication, Authorisation, and Accounting) per gli utenti che si connettono e utilizzano un servizio di rete.

Il server del captive portal comunica con un server RADIUS per autorizzare l'indirizzo MAC dell'ospite sul gateway di rete una volta soddisfatti i criteri di autenticazione.

System Font Stack

Una dichiarazione CSS font-family che dà priorità ai font preinstallati del sistema operativo (come San Francisco su iOS, Segoe UI su Windows e Roboto su Android) rispetto ai web font esterni.

L'implementazione di un system font stack garantisce il rendering immediato dei caratteri senza attivare richieste HTTP esterne bloccate verso servizi come Google Fonts.

Canary URL

Un URL HTTP dedicato e non crittografato gestito dai fornitori del sistema operativo (ad es. captive.apple.com) per verificare se un dispositivo ha una connettività internet illimitata.

Il gestore di rete in background del sistema operativo controlla questo URL per rilevare la presenza di un Captive Portal e attivare il popup webview del CNA.

Passpoint (Hotspot 2.0)

Uno standard di settore sviluppato dalla WiFi Alliance che consente ai dispositivi mobili di rilevare automaticamente ed effettuare l'autenticazione in modo sicuro con gli hotspot WiFi, bypassando i login manuali tramite Captive Portal.

Le aziende utilizzano Passpoint insieme a piattaforme come Purple per far passare gli ospiti da splash page complesse a esperienze di roaming protette e fluide simili a quelle della rete cellulare.

Esempi pratici

Una catena alberghiera di lusso con 250 camere [Hospitality](/industries/hotels) desidera implementare una pagina di accesso WiFi personalizzata per gli ospiti che si adatti perfettamente alle linee guida del proprio marchio premium. La loro agenzia creativa ha progettato una splash page che utilizza una tipografia personalizzata del brand (ospitata su Adobe Fonts), molteplici immagini di sfondo ad alta risoluzione (ospitate su un bucket AWS S3 pubblico) e una procedura guidata JavaScript animata in più passaggi. Una volta distribuito, gli ospiti iOS si connettono al SSID, ma il portale viene visualizzato come una schermata bianca vuota e gli utenti non sono in grado di autenticarsi.

Per risolvere la schermata bianca e il branding non funzionante, dobbiamo ristrutturare l'architettura frontend del portale per renderla conforme ai vincoli della sandbox Apple CNA:

  1. Risoluzione della tipografia: Poiché Adobe Fonts richiede una richiesta HTTP esterna che viene bloccata dalla CNA, sostituiamo la chiamata al carattere personalizzato con uno stack di caratteri di sistema nativo e premium (font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;). Ciò garantisce un rendering istantaneo senza chiamate di rete esterne.
  2. Ottimizzazione delle risorse: Le immagini di sfondo su AWS S3 sono bloccate perché S3 non si trova nel walled garden del gateway. Comprimiamo il logo principale del brand, lo convertiamo in un SVG leggero e lo codifichiamo direttamente nell'HTML come Data URI Base64. Per lo sfondo, sostituiamo le immagini pesanti con un gradiente CSS pulito e reattivo utilizzando i colori del brand dell'hotel, riducendo significativamente il peso della pagina.
  3. Semplificazione di JavaScript: La procedura guidata animata in più passaggi si affida a librerie jQuery e GSAP esterne. Eliminiamo queste dipendenze esterne e rifattorizziamo il modulo in una struttura HTML a pagina singola e a colonna singola. La convalida del modulo viene riscritta in JavaScript nativo e leggero.
  4. Handshake di autenticazione: L'invio del modulo viene modificato da un invio basato su AJAX a un modulo HTML nativo <form action=\"/submit\" method=\"POST\"> per attivare un reindirizzamento a pagina intera, consentendo al Websheet iOS di eseguire il suo controllo canary e visualizzare il pulsante "Fine".
Commento dell'esaminatore: Questo scenario rappresenta il classico conflitto tra il design creativo di fascia alta e i rigidi vincoli di sicurezza delle webview captive. Le agenzie creative spesso trattano il Captive Portal come un sito web desktop standard. Tuttavia, poiché il dispositivo si trova in uno stato di pre-autenticazione, la rete blocca tutto il traffico esterno. Inserendo il CSS inline, utilizzando font di sistema, codificando le risorse in Base64 e utilizzando invii di moduli nativi, preserviamo l'estetica premium del brand ottenendo al contempo l'affidabilità operativa al 100% sui dispositivi iOS e Android.

Una catena di vendita al dettaglio nazionale [Retail](/industries/retail) con 450 negozi desidera acquisire le e-mail degli ospiti tramite splash page WiFi per alimentare il proprio CRM. Richiedono agli ospiti di prestare il consenso alla ricezione di newsletter di marketing. Il design iniziale presenta una casella di controllo preselezionata "Accetto di ricevere e-mail di marketing". Inoltre, il portale è ospitato su un singolo server locale nella loro sede centrale. Durante le ore di punta (sabato pomeriggio), gli ospiti di tutto il paese subiscono gravi ritardi e molti non riescono a caricare la pagina di accesso, con conseguente enorme calo dei tassi di acquisizione dei dati.

Dobbiamo affrontare sia la violazione della conformità sia il collo di bottiglia dell'infrastruttura:

  1. Risoluzione della Conformità: Ai sensi del GDPR e della CCPA, le caselle di consenso preselezionate sono illegali. Modifichiamo l'HTML per rendere la casella di controllo del consenso al marketing non selezionata per impostazione predefinita (<input type="checkbox" id="marketing_consent">). Aggiungiamo anche una casella di controllo obbligatoria e separata per i Termini di Servizio per disaccoppiare l'accordo legale dall'adesione al marketing.
  2. Scalabilità dell'Infrastruttura: L'hosting di un captive portal nazionale su un unico server centralizzato crea un singolo punto di vulnerabilità e un enorme collo di bottiglia nella latenza. Migriamo il frontend del portale su una Content Delivery Network (CDN) altamente disponibile e distribuita a livello globale con memorizzazione nella cache edge.
  3. Integrazione RADIUS: Configuriamo gli access point dei negozi locali affinché puntino a un cluster RADIUS cloud-native con ridondanza active-active, garantendo che le richieste di autenticazione vengano elaborate localmente all'edge con una latenza inferiore a 50 ms, anche durante i picchi di traffico del sabato.
  4. Migrazione a Purple: Per eliminare completamente questo sovraccarico ingegneristico, il rivenditore migra a Purple. Gli strumenti di consenso integrati conformi al GDPR di Purple gestiscono automaticamente le adesioni conformi, e la loro infrastruttura cloud distribuita a livello globale gestisce milioni di autenticazioni giornaliere con un uptime del 99,99%, risolvendo completamente il collo di bottiglia della scalabilità.
Commento dell'esaminatore: Le caselle di consenso preselezionate rappresentano un grave rischio di conformità che può portare a massicce sanzioni normative. Disaccoppiare il consenso al marketing dai Termini di Servizio è una best practice tecnica e legale. Dal punto di vista dell'infrastruttura, l'hosting centralizzato dei captive portal è un anti-pattern. Una presenza commerciale su scala nazionale richiede un frontend decentralizzato con memorizzazione nella cache edge, combinato con un backend RADIUS cloud-native. La migrazione a una piattaforma gestita come Purple elimina questa complessità architetturale, consentendo al rivenditore di concentrarsi sulle campagne di marketing anziché sulla scalabilità del database.

Domande di esercitazione

Q1. Un team IT di un importante aeroporto internazionale [Transport](/industries/trains) distribuisce un Captive Portal con codice personalizzato. Notano che, mentre gli utenti Android si connettono senza problemi, una parte significativa di utenti iOS riscontra un problema per cui l'autenticazione va a buon fine ma non riescono a navigare sul web. A un esame più attento, i dispositivi iOS mostrano di essere connessi all'SSID, ma il pulsante in alto a destra sul popup captive mostra ancora la scritta 'Annulla' invece di 'Fine'. Qual è la causa principale di questo problema e come dovrebbe risolverlo lo sviluppatore?

Suggerimento: Analizza come l'assistente CNA di Apple rileva che una rete è passata dallo stato captive a quello autenticato e quale azione del browser è richiesta per attivare questo controllo.

Visualizza risposta modello

La causa principale è che la pagina di successo del portale aggiorna l'interfaccia utente in modo dinamico tramite JavaScript (routing AJAX/SPA) anziché eseguire una navigazione HTTP a pagina intera. Il mini-browser Captive Network Assistant (CNA) di Apple iOS esegue nuovamente il controllo di connettività in background (la richiesta canary a captive.apple.com) solo quando si verifica un reindirizzamento o una navigazione URL a pagina intera. Se lo sviluppatore invia il modulo di login tramite AJAX e mostra semplicemente un messaggio di 'Successo' nel DOM, il CNA non si accorge che la rete è stata sbloccata. Di conseguenza, il pulsante in alto a destra rimane impostato su 'Annulla'. Se l'utente fa clic su 'Annulla' per uscire, il sistema operativo presume che il login sia fallito e si disconnette dalla rete WiFi.

Soluzione: Lo sviluppatore deve modificare il gestore dell'autenticazione riuscita per forzare un reindirizzamento a pagina intera. Questo si può ottenere inviando il modulo di login in modo nativo tramite un tag HTML standard <form action="/submit" method="POST"> oppure eseguendo window.location.href = '/success_landing_page' in JavaScript una volta che l'API restituisce una risposta di autenticazione corretta. Ciò attiva il caricamento della pagina intera richiesto, costringendo l'assistente CNA a rivalutare lo stato della rete, verificare che il Canary URL sia ora raggiungibile e cambiare il pulsante in alto a destra in 'Fine'.

Q2. Un team di gestione di uno stadio [Events] desidera lanciare una rete WiFi per gli ospiti che acquisisca gli opt-in di marketing. Il responsabile della conformità insiste sul fatto che il portale debba essere conforme al 100% al GDPR. Il team di sviluppo presenta un mockup in cui il modulo di login ha una casella preselezionata con scritto 'Accetto i Termini di Servizio e acconsento a ricevere newsletter di marketing'. Perché questo design non è conforme e come dovrebbero essere ristrutturati l'HTML/CSS e il modulo per soddisfare il GDPR mantenendo un tasso di conversione elevato?

Suggerimento: Considera i severi requisiti del GDPR in materia di consenso esplicito, la separazione dell'opt-in di marketing dai termini di servizio e la visibilità fisica dei testi legali sugli schermi dei dispositivi mobili.

Visualizza risposta modello

Il design proposto viola il GDPR su due fronti principali: in primo luogo, le caselle di controllo preselezionate non costituiscono un consenso valido, che deve essere liberamente fornito, specifico, informato e inequivocabile. In secondo luogo, associare il consenso al marketing all'accettazione dei Termini di Servizio non è conforme; un utente non può essere obbligato ad accettare email di marketing come condizione per utilizzare il servizio WiFi.

Strategia di Refactoring:

  1. Disaccoppiare il Consenso: Dividere la casella di controllo in due caselle distinte. La Casella A è obbligatoria e copre i Termini di Servizio e l'Informativa sulla Privacy. La Casella B è facoltativa e copre l'iscrizione alla newsletter di marketing.
  2. Impostare come Non Selezionato: Assicurarsi che entrambe le caselle di controllo siano deselezionate per impostazione predefinita nell'HTML (attributo checked omesso).
  3. Visibilità CSS: Poiché oltre il 90% degli utenti naviga da dispositivi mobili, posizionare le caselle di controllo direttamente sopra il pulsante "Connetti" in modo che siano visibili "above the fold" senza dover scorrere. Utilizzare una serie di font di sistema e impostare la dimensione del carattere dell'etichetta a 14px con una line-height di 1.4 per favorire la leggibilità.
  4. Scrollbox per i Termini: Per evitare che il testo legale spinga gli elementi del modulo fuori dallo schermo, inserire i Termini di Servizio dettagliati in un contenitore scorrevole con altezza fissa (max-height: 100px; overflow-y: auto; background-color: #F5F1ED; border: 1px solid #D1D5DB; border-radius: 6px;) che può essere aperto o chiuso tramite un link testuale. Questo mantiene un layout pulito e ad alta conversione, garantendo al contempo l'assoluta conformità legale.

Q3. Una catena retail [Retail](/industries/retail) sta distribuendo una splash page con codice personalizzato in 100 punti vendita. Il designer ha utilizzato Google Fonts (Montserrat) e ha inserito nell'head HTML un link a un foglio di stile Bootstrap ospitato su CDN. Durante i test su una rete aziendale, la pagina viene visualizzata magnificamente. Tuttavia, quando viene distribuita su un AP di un negozio di prova con una configurazione di rete captive, la pagina viene visualizzata con un testo Times New Roman non formattato, allineamento interrotto e icone mancanti. Perché succede questo e come devono essere ristrutturati gli asset?

Suggerimento: Analizzare lo stato della connessione di rete prima che un utente sia autenticato e determinare come il browser gestisce le richieste HTTP esterne verso domini al di fuori del walled garden.

Visualizza risposta modello

Questo errore si verifica perché il dispositivo si trova in uno stato captive non autenticato quando viene caricata la splash page. In questo stato, il gateway wireless blocca tutto il traffico internet in uscita, consentendo le richieste solo ai domini esplicitamente inseriti nella whitelist del Walled Garden del gateway. Poiché i domini CDN per Bootstrap (cdn.jsdelivr.net) e Google Fonts (fonts.googleapis.com) non sono inseriti nella whitelist, le richieste del browser per recuperare il foglio di stile e i file dei font falliscono silenziosamente. Di conseguenza, il browser ripiega sul suo motore di rendering predefinito, generando un HTML privo di stile (testo Times New Roman) e layout compromessi.

Strategia di Refactoring:

  1. CSS Inline: Rimuovere il collegamento esterno al foglio di stile Bootstrap. Copiare le regole CSS grid/flexbox necessarie direttamente in un blocco <style> all'interno del tag <head> dell'HTML. Ciò garantisce che tutte le istruzioni di layout vengano fornite nel payload iniziale della singola pagina.
  2. Implementare Font di Sistema: Rimuovere la chiamata @import o il tag <link> di Google Fonts. Sostituirli con una serie di font di sistema nativi nel CSS (font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;). Questo costringe il dispositivo a utilizzare font di alta qualità già preinstallati sul sistema operativo, eliminando completamente la dipendenza da reti esterne.
  3. Codificare icone e loghi in Base64: Se il layout si affida a immagini esterne o librerie di icone (come FontAwesome), convertire queste icone in formato SVG e incorporarle inline all'interno dell'HTML o come Data URI Base64 nel CSS. Questo garantisce che la pagina sia autonoma al 100% e venga visualizzata perfettamente anche in assenza totale di connettività internet.

Domande frequenti

Che cos'è il Captive Network Assistant (CNA) e perché l'HTML e il CSS dei Captive Portal personalizzati si comportano diversamente al suo interno?

Il Captive Network Assistant (CNA) è una webview protetta e limitata che viene avviata automaticamente dai sistemi operativi come iOS, macOS, Android e Windows quando rilevano un'intercettazione di rete. I CNA non dispongono di tutte le funzionalità del browser: bloccano frequentemente i popup, limitano la memorizzazione dei cookie persistenti, riducono la velocità di esecuzione di JavaScript, disabilitano i download di file e impongono rigidi limiti alla viewport. I file HTML e CSS del Captive Portal personalizzato devono essere leggeri, autonomi ed evitare reindirizzamenti esterni che possono interrompere prematuramente la sessione CNA.

Quali domini e indirizzi IP devono essere inclusi nel walled garden di un Captive Portal?

Un walled garden (lista di consentiti pre-autenticazione) consente ai client wireless non autenticati di raggiungere risorse critiche prima di effettuare l'accesso. È necessario includere gli hostname per tutti i fogli di stile CSS ospitati esternamente, i pacchetti JavaScript, i web font o le risorse CDN utilizzati sulla splash page. Se si supporta l'accesso tramite social o la verifica tramite SMS, è necessario inserire nella lista di consentiti anche gli endpoint di autenticazione per Apple, Google o i gateway SMS, oltre al reindirizzamento del controller e agli endpoint API RFC 8908.

In che modo le specifiche RFC 8908 e RFC 8910 modernizzano il rilevamento del Captive Portal rispetto al tradizionale reindirizzamento HTTP?

I Captive Portal tradizionali intercettano le richieste HTTP in chiaro (porta 80) e restituiscono un reindirizzamento HTTP 302, che causa avvisi sui certificati SSL/TLS se il client tenta una connessione HTTPS. Le specifiche RFC 8908 e RFC 8910 stabiliscono un'API standardizzata per i Captive Portal in cui la rete wireless segnala l'URL di un'API tramite l'opzione DHCP 114 o l'opzione di annuncio router IPv6 38. Il sistema operativo del client interroga direttamente questo endpoint JSON, ricevendo in modo esplicito lo stato del captive, i termini della sede e gli URL di autenticazione senza manomissioni dei pacchetti o errori di certificato.

Quali pattern di design CSS funzionano meglio per le splash page dei captive portal sui dispositivi mobili?

Le best practice per il CSS del captive portal includono l'uso di layout fluidi Flexbox o CSS Grid, l'impostazione di target di tocco interattivi di almeno 48x48 pixel per l'ergonomia del touch, l'affidamento a font di sistema (come -apple-system, BlinkMacSystemFont, Segoe UI) per evitare download di webfont che bloccano il rendering, l'inserimento in linea di icone SVG critiche per ridurre al minimo le richieste HTTP e la specifica di un meta tag viewport mobile rigoroso (width=device-width, initial-scale=1) per prevenire fastidiosi scorrimenti orizzontali all'interno dei mini-browser.

In che modo Purple semplifica l'implementazione di captive portal personalizzati e la gestione del walled garden?

Purple sostituisce i fragili server web self-hosted con una piattaforma cloud enterprise per captive portal. Purple offre strumenti di branding dinamico, orchestrazione automatizzata del walled garden su Cisco Meraki, HPE Aruba, Ruckus, Ubiquiti UniFi e Fortinet, supporto completo dello standard RFC 8908 e rigorosi test di compatibilità sui webview CNA di iOS e Android, supportati da un uptime cloud del 99,99% e integrazioni di marketing CRM.

Continua a leggere questa serie

Ubiquiti UniFi guest portal non reindirizza: cause e soluzioni

Questa guida isola un errore di reindirizzamento del portale ospiti UniFi analizzando in sequenza lo stato dell'ospite, il reindirizzamento, il percorso di pre-autorizzazione e l'autorizzazione del controller. Fornisce ai team IT locali un metodo collaudato per risolvere i dubbi tra rete ospiti e Hotspot, i passaggi ai portali esterni, i requisiti correnti degli account UniFi OS e i test di isolamento DNS.

Leggi la guida →

Cisco Meraki splash page non funzionante: un diagramma di flusso per la risoluzione dei problemi

Questa guida pratica per il secondo giorno isola il punto in cui un flusso di splash Cisco Meraki ha fallito: autorizzazione del client, avvio del redirect HTTP, raggiungibilità del walled garden o sign-on RADIUS. Fornisce ai team IT delle sedi un percorso di prove controllato per ripristinare il WiFi per gli ospiti senza apportare modifiche estese a un'infrastruttura attiva.

Leggi la guida →

Guida alla configurazione del WiFi ospiti aziendale: segmentazione VLAN, sicurezza e Captive Portals

Questa guida tecnica mostra ai team IT come configurare il WiFi ospiti come servizio di accesso internet controllato, utilizzando la segmentazione VLAN, le policy del firewall e un Captive Portal. Spiega inoltre come i moduli di registrazione e i controlli di onboarding di Purple supportino un'esperienza per i visitatori proporzionata senza indebolire il perimetro che circonda il personale, i pagamenti e i sistemi operativi.

Leggi la guida →

Hai domande sulla tua configurazione specifica?

Il nostro team collabora con gestori di sedi, responsabili IT e ingegneri di rete in 80.000 sedi. Prenota una chiamata di 20 minuti e ti mostreremo come altri professionisti come te hanno risolto il problema.