Vai al contenuto principale

Captive Portal personalizzato: Guida a 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 landing page per un Captive Portal personalizzato. Fornisce a sviluppatori frontend e architetti di rete strategie attuabili per navigare negli ambienti Apple CNA e webview Android, garantendo esperienze WiFi per gli ospiti perfette al pixel, conformi e ad altissime prestazioni.

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

Video overview

Ascolta questa guida

Visualizza trascrizione del podcast
Captive Portal personalizzato: Guida a HTML e CSS — Un briefing tecnico di Purple [INTRODUZIONE] Benvenuti nella serie di briefing tecnici di Purple. Oggi approfondiremo un aspetto che interessa ogni singola implementazione di guest WiFi: 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 vi siete mai connessi al WiFi di un hotel e vi siete trovati davanti a una splash page non funzionante - con immagini mancanti, testo privo di stile, un pulsante di accesso che non risponde al tocco - avete 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 voi. 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. Copriremo la struttura HTML, le regole CSS fondamentali, i vincoli del mini-browser CNA di Apple che mettono in difficoltà anche gli sviluppatori più esperti, e come piattaforme come il builder di portali di Purple possano eliminare del tutto la maggior parte di questa complessità. Entriamo nel vivo. [APPROFONDIMENTO TECNICO] Per prima cosa, stabiliamo cosa sia 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 - inserendo un'e-mail, accettando i termini, accedendo tramite social - e la rete concede quindi l'accesso completo a Internet. L'aspetto fondamentale da capire è dove viene renderizzata questa pagina. Sui dispositivi iOS, si apre all'interno del Captive Network Assistant di Apple - il CNA - che è una visualizzazione web WebKit ridotta all'essenziale. Non si tratta di 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 renderizzato a una risoluzione fissa di 900 per 572 pixel. Su Android, i dispositivi moderni utilizzano Chrome Custom Tabs, che sono notevolmente più efficienti. 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 testano sul proprio telefono Android, tutto sembra perfetto, e poi gli ospiti dell'hotel dotati di iPhone si ritrovano con una schermata bianca con testo privo di stile. Parliamo quindi di come scrivere codice in modo difensivo. La regola d'oro per l'HTML e il CSS del captive portal è questa: trattare la pagina come se non avesse alcuna connessione a Internet. Perché durante la fase di autenticazione, effettivamente non ce l'ha. La rete è captive. Qualsiasi risorsa che la pagina tenti di caricare da un URL esterno - un Google Font, un foglio di stile ospitato su CDN, una libreria JavaScript, l'immagine di un logo - non funzionerà, oppure causerà un'icona di caricamento infinito che non si risolverà mai. Iniziamo con la struttura HTML. Il tuo documento deve essere una pagina HTML5 pulita. Nell'head, devi inserire un meta tag viewport con attributo content impostato su width=device-width e initial-scale=1. Questo è un requisito non negoziabile per il rendering su dispositivi mobili. Senza di esso, iOS eseguirà il rendering della pagina a una larghezza di 980 pixel e la rimpiccolirà, rendendo ogni elemento microscopico. Il tuo CSS deve essere in linea - o in un blocco di stile all'interno dell'elemento head, o come attributi di stile in linea 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 captive non può raggiungere durante l'autenticazione. La pagina verrebbe renderizzata completamente priva di stile. Per i font, utilizza un set 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 tuo font di fallback sarà il Times New Roman, che non è l'esperienza di brand per cui il tuo cliente sta pagando. Per le immagini - il tuo logo, la grafica di sfondo, gli elementi decorativi - hai due opzioni. Puoi servirle dallo stesso server del Captive Portal, il che significa che si trovano sulla stessa rete locale e sono accessibili prima del completamento dell'autenticazione. Oppure, ancora meglio, puoi codificarle come URI di dati Base64 direttamente nel tuo codice HTML o CSS. Questo elimina completamente qualsiasi dipendenza esterna. Parliamo ora del layout della pagina. Poiché oltre il novanta percento degli accessi al Captive Portal avviene su dispositivi mobili, il tuo design dovrebbe essere mobile-first. Ciò significa un layout a colonna singola, con una larghezza massima di circa 480 pixel, centrato sulla pagina. Usa flexbox sull'elemento body - display flex, flex-direction column, align-items center, justify-content center, min-height 100 viewport height. Questo centra il tuo pannello dei contenuti verticalmente e orizzontalmente su qualsiasi dimensione dello schermo. Il tuo pulsante di invito all'azione primario deve essere facile da toccare. Le Human Interface Guidelines di Apple specificano un target di tocco minimo di 44 per 44 pixel. In pratica, per una CTA primaria, è preferibile un'altezza di circa 48 pixel, a larghezza intera all'interno del contenitore, con un raggio del bordo compreso tra 8 e 12 pixel. Per i campi del modulo - input dell'email, input del nome - imposta la dimensione del carattere ad almeno 16 pixel. Questo è fondamentale. Safari su iOS e il CNA ingrandiranno automaticamente qualsiasi campo di input con una dimensione del carattere inferiore a 16 pixel, compromettendo il tuo layout accuratamente progettato. Impostare la dimensione del carattere a 16 pixel o superiore previene questo comportamento di zoom. La sezione relativa al consenso legale merita una particolare attenzione. Ai sensi del GDPR, se raccogli dati personali - anche solo un indirizzo email - hai bisogno di un consenso esplicito e informato. Ciò significa una casella di controllo deselezionata per impostazione predefinita, con un'etichetta visibile che dichiari 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 dover scorrere la pagina. Ora, un dettaglio di implementazione cruciale specifico per iOS CNA. Quando l'utente completa l'autenticazione, il CNA monitora se il dominio captive è diventato accessibile. Il controllo viene attivato dalla navigazione completa della pagina, 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 il completamento dell'autenticazione. È necessario reindirizzare a un nuovo URL dopo l'autenticazione - un reindirizzamento HTTP completo, non una manipolazione del DOM tramite JavaScript. Questo è uno degli errori più comuni nello sviluppo di un Captive Portal. Per quanto riguarda 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 in JavaScript nativo vanno bene. jQuery è una dipendenza esterna da 30 kilobyte che non si caricherà. [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 completo della pagina all'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 essere 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, parliamo onestamente della scelta tra build e 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 tuoi punti di accesso e l'applicazione continua di patch di sicurezza. Si tratta di un impegno ingegneristico notevole. Il builder 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 al pixel, gestendo al contempo tutta l'infrastruttura backend - l'autenticazione, la cattura dei dati, l'analisi, gli strumenti di conformità al GDPR e le integrazioni di rete con oltre 200 fornitori di punti di accesso. Ottieni 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 precedenti 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 contesto browser standard. L'Apple CNA e le webview Android impongono rigide limitazioni alle risorse esterne, ai cookie, a JavaScript e allo stato della sessione. La soluzione è 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 valutano le proprie opzioni: se il vostro requisito è un portale completamente personalizzato con il vostro brand 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 oltre a un'infrastruttura di backend di livello di produzione. I prossimi passi da qui: esamina 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, usa la struttura del template HTML che abbiamo delineato come base di partenza. Grazie per l'attenzione e ci vediamo al prossimo briefing.

Parte della nostra serie principale: Guida al Captive Portal

Captive Portal personalizzato: Guida a HTML e CSS

Executive Summary

Per le sedi aziendali - che spaziano dagli hotel di lusso Hospitality e catene retail 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 severamente l'esecuzione di JavaScript per mitigare 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 compromessi, elementi del brand mancanti e pulsanti di accesso non funzionanti, con un impatto diretto sulla soddisfazione del cliente e sul coinvolgimento digitale. Questa guida fornisce soluzioni a queste sfide, presentando pratiche di codifica difensive - come CSS inline, codifica delle risorse in Base64, stack di font di sistema e handshake di autenticazione espliciti guidati dalla navigazione - per garantire una visualizzazione cross-platform fluida. Inoltre, esaminiamo come l'utilizzo di una soluzione gestita come il costruttore 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 SSID aperto.

Il Ciclo di Vita del Captive Portal

Quando un dispositivo client si associa a un SSID captive, viene avviata 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 indipendente dal fornitore (ad esempio, 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 landing page del captive portal tramite un reindirizzamento HTTP 302 [2].
  4. Generazione della Webview: Rilevando il reindirizzamento, il sistema operativo genera il proprio mini-browser nativo Captive Network Assistant (CNA) 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 a 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 a 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 di 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à, mostrando una schermata vuota.

  • Mitigazione: Mantieni un elenco Walled Garden rigoroso e minimale. Se utilizzi gli accessi social, inserisci nella whitelist i domini wildcard specifici consigliati dai provider di identità (ad es. *.google.com, *.gstatic.com).

3. Vulnerabilità di Session Timeout e MAC Spoofing

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 richiesto ripetutamente di ripetere l'autenticazione, compromettendo l'esperienza utente [1].

  • Mitigazione: Implementa session timeout ragionevoli (ad es. 24 ore) sul server RADIUS per prevenire sessioni inattive, 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 del Prodotto Purple: Sviluppo Interno vs. Acquisto

Sebbene la codifica di una singola pagina HTML sia semplice, ospitare, proteggere e scalare un'infrastruttura di Captive Portal personalizzata comporta 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 in Self-Hosting Piattaforma Purple Enterprise WiFi
Personalizzazione HTML/CSS Codifica completamente manuale, caricamento dei file sui singoli AP o server web locali. Editor per sviluppatori pixel-perfect che consente inserimenti di HTML/CSS personalizzati, combinato con un builder visivo drag-and-drop.
Infrastruttura RADIUS È necessario distribuire, configurare e mantenere server FreeRADIUS o Cloud RADIUS ad alta disponibilità [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 la crittografia sicura del database e i flussi di lavoro per la cancellazione dei dati. Completamente conforme fin dalla progettazione. Gestione del consenso integrata, richieste di cancellazione dei dati degli interessati automatizzate e hosting sicuro certificato ISO 27001.
Analytics & Marketing Richiede la creazione di pipeline personalizzate per l'acquisizione dei dati e l'integrazione di strumenti di marketing di terze parti. Dashboard di analytics di livello enterprise con tracciamento delle presenze in tempo reale, metriche sul tasso di ritorno e trigger per campagne di marketing automatizzate [6].
Integrazioni con Identity Provider Integrazioni OAuth2 manuali 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 progettazione dell'infrastruttura backend necessaria per supportare l'autenticazione RADIUS sicura su scala.

ROI e impatto aziendale

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 distribuzioni su larga scala, come uno stadio o una catena di vendita al dettaglio multi-sito, un Captive Portal malfunzionante è una delle cause principali dell'aumento dei ticket di supporto IT. Quando gli ospiti visualizzano una "schermata bianca" o un pulsante di accesso che non risponde, sovraccaricano il personale in loco o inviano ticket di supporto.

$$\text{Risparmio annuale sul supporto} = (\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 annuali. 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 prima di tutto per i dispositivi mobili riduce il tasso di errore del portale a <0,1%, eliminando quasi del tutto questo spreco operativo.

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

Per i punti vendita al dettaglio e i luoghi di ospitalità, il portale WiFi per gli ospiti è il meccanismo principale per acquisire dati dei clienti di prima parte puliti. Un'interfaccia utente progettata male, con testo microscopico o un layout del modulo macchinoso, 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 negozi 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 singolo per l'inserimento dell'e-mail (dimensione font: 16px) e un pulsante con area tattile ottimizzata da 48px, hanno registrato un incremento 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, solitamente 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 sul portale.

Le visualizzazioni web dei CNA impongono limitazioni rigide, tra cui il blocco delle CDN esterne, dei cookie persistenti e dello storage locale, che spesso compromettono i normali design web.

Walled Garden

Un elenco limitato di indirizzi IP, subnet o nomi di dominio a cui un utente ospite non autenticato è autorizzato ad accedere attraverso il gateway prima di completare la procedura di accesso al Captive Portal.

Gli sviluppatori devono assicurarsi che qualsiasi risorsa esterna (come le API per il login social 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 i dati binari (come le immagini) come una stringa ASCII, consentendo di incorporare le risorse direttamente nei documenti HTML o CSS.

L'utilizzo della codifica Base64 per loghi e icone elimina le richieste HTTP esterne, garantendo che gli elementi grafici vengano visualizzati perfettamente negli 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) 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à la 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 la visualizzazione immediata dei caratteri tipografici senza attivare richieste HTTP esterne bloccate verso servizi come Google Fonts.

Canary URL

Un URL HTTP dedicato e non crittografato gestito dai produttori di sistemi operativi (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 la finestra popup del CNA.

Passpoint (Hotspot 2.0)

Uno standard di settore sviluppato da WiFi Alliance che consente ai dispositivi mobili di rilevare e autenticarsi automaticamente e in modo sicuro con gli hotspot WiFi, evitando l'accesso manuale tramite Captive Portal.

Le aziende utilizzano Passpoint insieme a piattaforme come Purple per far passare gli ospiti da splash page complesse a un'esperienza di roaming sicuro e fluido simile a quella cellulare.

Esempi pratici

Una catena di hotel di lusso con 250 camere [Hospitality](/industries/hospitality) desidera implementare una pagina di login WiFi per gli ospiti personalizzata che si adatti perfettamente alle linee guida del loro brand premium. La loro agenzia creativa ha progettato una splash page che utilizza una tipografia del brand personalizzata (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 implementata, gli ospiti iOS si connettono al SSID, ma il portale appare come una schermata bianca vuota e gli utenti non sono in grado di autenticarsi.

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

  1. Risoluzione della tipografia: Poiché Adobe Fonts richiede una richiesta HTTP esterna che viene bloccata dal CNA, sostituiamo la chiamata al font personalizzato con uno stack di font 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 che utilizza i colori del brand dell'hotel, riducendo significativamente il peso della pagina.
  3. Semplificazione di JavaScript: La procedura guidata animata in più passaggi si basa su librerie esterne jQuery e GSAP. Eliminiamo queste dipendenze esterne e rifattorizziamo il modulo in una struttura HTML a pagina singola e colonna singola. La convalida del modulo è 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 a iOS Websheet 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 alto livello 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 in linea, utilizzando i font di sistema, codificando le risorse in Base64 e utilizzando gli invii di moduli nativi, preserviamo l'estetica del brand premium garantendo 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 le 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 unico 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 login, con una conseguente massiccia interruzione dei tassi di acquisizione dei dati.

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

  1. Risoluzione della conformità: Ai sensi del GDPR e del CCPA, le caselle di consenso preselezionate sono illegali. Modifichiamo l'HTML per deselezionare di default la casella di controllo del consenso al marketing (<input type="checkbox" id="marketing_consent">). Aggiungiamo anche una casella di controllo obbligatoria separata per i Termini di servizio per scindere l'accordo legale dall'adesione al marketing.
  2. Scalabilità dell'infrastruttura: L'hosting di un Captive Portal nazionale su un singolo server centralizzato crea un singolo punto di vulnerabilità e un enorme collo di bottiglia per la latenza. Migriamo il frontend del portale su una Content Delivery Network (CDN) altamente disponibile e distribuita a livello globale con edge-caching.
  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 gestione del consenso integrati di Purple conformi al GDPR gestiscono automaticamente le adesioni a norma di legge, e la loro infrastruttura cloud distribuita a livello globale gestisce milioni di autenticazioni quotidiane con un uptime del 99,99%, risolvendo del tutto 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. Scindere 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 retail su scala nazionale richiede un frontend decentralizzato con edge-caching 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/transport) implementa 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 si autenticano correttamente ma non riescono a navigare sul web. A un esame più attento, i dispositivi iOS mostrano di essere connessi al SSID, ma il pulsante in alto a destra sulla popup di login dice ancora 'Annulla' anziché 'Fine'. Qual è la causa principale di questo problema e come dovrebbe risolverlo lo sviluppatore?

Suggerimento: Analizza in che modo l'assistente CNA di Apple rileva che una rete è passata dallo stato captive a quello autenticato e quale azione del browser è necessaria 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 rende conto 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 presuppone che il login sia fallito e si disconnette dalla rete WiFi.\n\nSoluzione: Lo sviluppatore deve modificare il gestore del successo dell'autenticazione per forzare un reindirizzamento a pagina intera. Questo può essere ottenuto inviando il modulo di login in modo nativo tramite un tag HTML standard <form action=\"/submit\" method=\"POST\"> o 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 valutare nuovamente 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 operativo di uno stadio [Events] vuole lanciare una rete WiFi per gli ospiti che acquisisca i consensi per il marketing. Il responsabile della conformità insiste sul fatto che il portale debba essere conforme al 100% al GDPR. Il team di sviluppo presenta un prototipo 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 la struttura del 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 tra l'adesione al marketing e i 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 costretto ad accettare email di marketing come condizione per l'utilizzo del servizio WiFi.

Strategia di Refactoring:

  1. Disaccoppiare il Consenso: Dividere la casella di controllo in due caselle separate. La casella A è obbligatoria e riguarda i Termini di Servizio e l'Informativa sulla Privacy. La casella B è facoltativa e riguarda l'adesione 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 utilizza dispositivi mobili, posizionare le caselle di controllo direttamente sopra il pulsante 'Connetti' in modo che siano visibili 'above the fold' senza dover scorrere. Utilizzare un set di font di sistema e impostare la dimensione del carattere dell'etichetta a 14px con un'altezza della riga di 1.4 per una migliore leggibilità.
  4. Scrollbox dei Termini: Per evitare che il testo legale spinga gli elementi del modulo fuori dallo schermo, posizionare 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. In questo modo si 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 negozi. Il designer ha utilizzato Google Fonts (Montserrat) e ha inserito nell'head HTML un collegamento a un foglio di stile Bootstrap ospitato su CDN. Durante i test su una rete aziendale, la pagina viene visualizzata perfettamente. Tuttavia, quando viene distribuita sull'AP di un negozio di prova con una configurazione di rete captive, la pagina viene visualizzata con testo non formattato in Times New Roman, 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 in modo silenzioso. Di conseguenza, il browser ripiega sul suo motore di rendering predefinito, generando un HTML non formattato (testo Times New Roman) e layout interrotti.

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> nell'head HTML <head>. Questo garantisce che tutte le istruzioni di layout vengano fornite nel payload iniziale a pagina singola.
  2. Implementare un set di font di sistema: Rimuovere la chiamata @import o <link> a Google Fonts. Sostituirla con un set di font di sistema nativo 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 dalla rete esterna.
  3. Codificare le icone/i 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 URI di dati Base64 nel CSS. Questo garantisce che la pagina sia autonoma al 100% e venga visualizzata perfettamente anche con una connettività Internet pari a zero.

Continua a leggere questa serie

Ubiquiti UniFi guest portal not redirecting: cause e soluzioni

Questa guida isola un errore di reindirizzamento del portale ospiti UniFi seguendo in sequenza lo stato dell'ospite, il reindirizzamento, la rotta di pre-autorizzazione e l'autorizzazione del controller. Fornisce ai team IT delle sedi un metodo collaudato per affrontare la confusione tra rete ospiti e Hotspot, i passaggi ai portali esterni, i requisiti attuali dell'account UniFi OS e i test di isolamento DNS.

Leggi la guida →

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

Questa guida pratica per la fase di post-installazione isola il punto in cui un flusso splash Cisco Meraki ha riscontrato un errore: autorizzazione del client, avvio del redirect HTTP, raggiungibilità del walled garden o sign-on RADIUS. Fornisce ai team IT delle sedi un percorso di verifica controllato, consentendo di ripristinare il WiFi per gli ospiti senza apportare modifiche generiche a un'intera infrastruttura attiva.

Leggi la guida →

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

Questa guida tecnica illustra ai team IT come configurare il WiFi ospiti come servizio di accesso a internet controllato, utilizzando la segmentazione VLAN, le policy del firewall e un captive portal. Spiega inoltre in che modo i moduli di registrazione e i controlli di onboarding di Purple offrono un'esperienza visitatore equilibrata senza compromettere la sicurezza dei sistemi del personale, di pagamento e 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.