- Purple
- Captive portals: a complete guide
- Captive Portal Personalizado: Guia de HTML e CSS
Captive Portal Personalizado: Guia de HTML e CSS
Este guia de referência técnica definitivo descreve os padrões de desenvolvimento, a arquitetura CSS e as restrições em nível de rede necessárias para projetar e programar uma página de destino de Captive Portal personalizada. Ele fornece a desenvolvedores frontend e arquitetos de rede estratégias práticas para navegar em ambientes Apple CNA e webview Android, garantindo experiências de WiFi para visitantes perfeitas, em conformidade e de alta performance.
Video overview
Ouça este guia
Ver transcrição do podcast
Parte da nossa série principal: Guia de Captive Portal →
- Resumo Executivo
- Detalhamento Técnico
- O Ciclo de Vida do Captive Portal
- Restrições de Mini-Navegadores Específicas de Plataforma
- Codificando ao Redor da Armadilha do Botão "Concluído" do Apple CNA
- Guia de Implementação
- A Regra de Ouro: Projete para Conectividade Zero à Internet
- 1. Configuração da Viewport
- 2. Incorporação de CSS e Remoção de Dependências Externas
- 3. Codificação de Ativos em Base64
- 4. Otimização de Campos de Entrada e Alvos de Toque
- 5. Consentimento Legal e Conformidade com a GDPR
- Modelo de CSS/HTML Customizado de Captive Portal
- Solução de Problemas e Mitigação de Riscos
- 1. O Loop de Aviso de Certificado SSL/TLS
- 2. Falhas de Resolução de DNS (A Armadilha do Walled Garden)
- 3. Vulnerabilidades de Limite de Tempo de Sessão e MAC Spoofing
- Relevância dos Produtos Purple: Construir vs. Comprar
- ROI & Business Impact
- 1. Operational Cost Reduction (IT Helpdesk Tickets)
- 2. Marketing Data Capture and Opt-in Optimisation
- 3. Legal and Regulatory Risk Mitigation
- Resumo dos Principais Aprendizados
- Referências
- Ouça o Briefing Técnico

Resumo Executivo
Para estabelecimentos corporativos - desde hotéis de luxo Hospitality e redes de varejo Retail até terminais de trânsito Transport e complexos médicos modernos Healthcare - a splash page de WiFi para convidados é a porta de entrada digital. No entanto, mais de 90% dos logins de WiFi para convidados ocorrem em dispositivos móveis, onde a renderização é governada não por navegadores padrão como Safari ou Chrome, mas por webviews restritas do Captive Network Assistant (CNA) [1]. Esses "mini-navegadores" impõem limitações severas de sandbox: eles bloqueiam CDNs externos, desabilitam cookies persistentes, ignoram fontes da web externas e restringem severamente a execução de JavaScript para mitigar riscos de segurança e evitar o sequestro de sessões [2].
Quando um desenvolvedor projeta uma splash page usando padrões web tradicionais, essas restrições resultam em layouts quebrados, elementos de marca ausentes e botões de login que não funcionam, impactando diretamente a satisfação do cliente e o engajamento digital. Este guia fornece soluções para esses desafios, apresentando práticas de codificação defensiva - como CSS inline, codificação de ativos em Base64, pilhas de fontes do sistema e handshakes de autenticação explícitos baseados em navegação - para garantir uma renderização multiplataforma perfeita. Além disso, examinamos como a utilização de uma solução gerenciada como o construtor de portais da Purple permite que os desenvolvedores mantenham o controle criativo total de HTML/CSS enquanto terceirizam a autenticação RADIUS, escalonamento de banco de dados, conformidade com GDPR/PCI e integrações de AP de múltiplos fornecedores [3].
Detalhamento Técnico
Para construir um Captive Portal personalizado e resiliente, os desenvolvedores devem compreender a interceptação em nível de rede e a virtualização de navegador que ocorrem quando um convidado se associa a um Service Set Identifier (SSID) aberto.
O Ciclo de Vida do Captive Portal
Quando um dispositivo cliente se associa a um SSID cativo, a seguinte sequência é iniciada:
- Associação de IP: O dispositivo conclui um handshake de 3 vias e solicita um endereço IP via DHCP.
- Sonda de Conectividade Ativa: O gerenciador de rede em segundo plano do sistema operacional envia imediatamente uma solicitação HTTP GET para uma URL canário dedicada e neutra em termos de fornecedor (por exemplo,
http://captive.apple.com/hotspot-detect.htmlda Apple ouhttp://connectivitycheck.gstatic.com/generate_204do Google) [1]. - Interceptação de DNS/HTTP: O Wireless LAN Controller (WLC) ou Access Point (AP) local intercepta essa solicitação HTTP na porta 80. Em vez de retornar o status HTTP 200 ou 204 esperado, o gateway redireciona o tráfego do cliente para a URL da página de destino do Captive Portal por meio de um redirecionamento HTTP 302 [2].
- Abertura de Webview: Ao detectar o redirecionamento, o SO abre seu mini-navegador nativo Captive Network Assistant (CNA) para exibir a splash page redirecionada, eliminando a necessidade de o usuário abrir manualmente um navegador completo.5. Autenticação e Transição de Estado: O usuário preenche o formulário de login, enviando as credenciais de volta para o servidor do portal, que instrui o gateway (geralmente via um RADIUS Access-Accept ou chamada de API externa) a autorizar o endereço MAC.
- Handshake de Saída do CNA: O mini-navegador CNA realiza outro HTTP GET para sua URL canário. Se receber a resposta esperada 200/204, ele altera o botão superior direito de "Cancelar" para "Concluído" e estabelece a conexão WiFi como a interface de rede principal.
Restrições de Mini-Navegadores Específicas de Plataforma
Cada sistema operacional lida com esse ciclo de vida dentro de diferentes ambientes de webview, resultando em um comportamento altamente fragmentado. A tabela abaixo detalha essas restrições críticas:
| Plataforma / Webview | Método de Exibição | Cookies Persistentes | Fontes Web Externas | Execução de JavaScript | Dimensões da Janela | Gatilho de Handshake de Saída |
|---|---|---|---|---|---|---|
| Apple iOS CNA (Websheet) | Popup de Mini-Navegador | Bloqueado (Destruído ao fechar) | Bloqueado (Offline) | Limitado (Sem localStorage/sessionStorage) | Responsivo (Largura do dispositivo) | Apenas Redirecionamento HTTP de Página Inteira [1] |
| Apple macOS CNA (Captive Network Assistant) | Popup de Mini-Navegador | Bloqueado | Bloqueado | Limitado (Sem caixas de diálogo alert/confirm) | Fixo (900px x 572px) | Apenas Redirecionamento HTTP de Página Inteira |
| Android (Google) (CaptivePortalLogin) | Notificação Push -> Chrome Custom Tab | Permitido (Compartilhado com o Chrome) | Permitido (Se na lista de permissões do walled garden) | Completo | Responsivo | Automático (Captive Portal API / Validação 204) [2] |
| Samsung Android (Samsung Internet) | Notificação Push -> Mini-Navegador | Permitido | Permitido | Completo | Responsivo | Automático |
| Windows 10/11 (Default Browser) | Inicialização Automática do Navegador Padrão | Permitido (Contexto completo do navegador) | Permitido | Completo | Responsivo | Manual / Automático |

Codificando ao Redor da Armadilha do Botão "Concluído" do Apple CNA
Um dos modos de falha mais frequentes no desenvolvimento de portais personalizados é a Armadilha do Botão "Concluído" em dispositivos iOS. Quando um usuário se autentica, a webview do Websheet do iOS deve detectar que a rede não é mais cativa. Ela faz isso monitorando o sucesso de suas requisições canário em segundo plano.
Fundamentalmente, o iOS CNA só acionará essa verificação mediante uma navegação HTTP de página inteira (redirecionamento de local). Se um desenvolvedor criar uma Single Page Application (SPA) moderna que envia dados de formulário por meio de uma chamada AJAX assíncrona (por exemplo, fetch() ou Axios) e atualiza o DOM dinamicamente sem alterar a URL, o CNA nunca executará novamente sua verificação de conectividade. O usuário será autenticado no nível do gateway, mas o botão do CNA no canto superior direito permanecerá como "Cancelar". Se o usuário frustrado clicar em "Cancelar", o dispositivo iOS irá se desassociar imediatamente do SSID, encerrando a sessão WiFi [1].
Para evitar isso, o manipulador de sucesso de autenticação deve realizar um redirecionamento de página inteira para uma página de destino física (por exemplo, window.location.href = '/success') ou enviar o formulário de login nativamente por meio de uma ação padrão HTTP POST.
Guia de Implementação
Para garantir uma renderização consistente em todas as plataformas, os desenvolvedores devem fazer a transição do web design moderno e repleto de ativos pesados para um estilo de codificação altamente independente e defensivo.
A Regra de Ouro: Projete para Conectividade Zero à Internet
Durante o estado cativo, o dispositivo cliente não tem acesso à internet em geral. Ele só pode resolver e acessar endereços IP e domínios explicitamente permitidos no Walled Garden do controlador sem fio (como o próprio IP do servidor do Captive Portal). Portanto, qualquer ativo externo referenciado em seu HTML falhará ao carregar, resultando em um layout quebrado.
Para projetar de forma defensiva, implemente a seguinte Lista de Verificação de Design de Captive Portal Mobile-First:

1. Configuração da Viewport
Para evitar que dispositivos móveis reduzam a escala da viewport para uma largura de desktop (normalmente 980px), o <head> HTML deve incluir uma meta tag de viewport responsiva. Sem isso, o texto e os campos de entrada parecerão microscópicos em dispositivos móveis:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
2. Incorporação de CSS e Remoção de Dependências Externas
Nunca faça links para arquivos CSS externos ou CDNs (por exemplo, Bootstrap, Tailwind ou Google Fonts). Todo o CSS deve ser incorporado dentro de um bloco <style> no <head> HTML.
Para tipografia, utilize uma pilha de fontes do sistema que faça referência a fontes locais pré-instaladas do sistema operacional. Isso evita totalmente as requisições HTTP e garante que a página seja carregada instantaneamente usando a fonte sans-serif nativa e de alta qualidade do 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ção de Ativos em Base64
Imagens, logotipos e ícones não devem ser referenciados por meio de URLs HTTP externas, a menos que o domínio de hospedagem esteja incluído na whitelist do jardim murado do gateway. O método mais confiável é codificar pequenos ativos visuais (como logotipos PNG ou SVG) diretamente no HTML ou CSS como Base64 Data URIs:
<!-- Exemplo de Logotipo Inline em Base64 -->
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iIzc0NThGRCIvPjwvc3ZnPg==" alt="Purple Logo" class="brand-logo">
4. Otimização de Campos de Entrada e Alvos de Toque
Para estar em conformidade com as diretrizes de usabilidade móvel (como as Diretrizes de Interface Humana da Apple), todos os elementos interativos devem ser otimizados para entrada por toque:
- Tamanho da Fonte de Entrada: O tamanho da fonte do texto de entrada deve ser de pelo menos 16px. Se o tamanho da fonte for menor (por exemplo, 14px), o Safari do iOS e o CNA farão zoom automaticamente no campo de entrada ao focar, distorcendo o layout da página [1].
- Alvos de Toque: Botões, caixas de seleção e links devem ter uma área mínima de alvo de toque de 44px x 44px para evitar cliques acidentais ou frustração do usuário.
5. Consentimento Legal e Conformidade com a GDPR
Ao capturar dados de visitantes (por exemplo, e-mail, número de telefone ou perfis sociais), a estrutura HTML deve dar suporte ao consentimento legal explícito. Sob a GDPR, caixas de seleção pré-marcadas ou declarações de consentimento implícito (por exemplo, "Ao fazer login, você concorda com nossos termos") não estão em conformidade [3].
- Forneça uma caixa de seleção desmarcada por padrão para Termos e Condições e Políticas de Privacidade.
- Envolva o texto legal detalhado em um contêiner rolável de altura limitada (
max-height: 120px; overflow-y: auto;) para manter o formulário de login principal visível sem rolar a página.
<div class="consent-container">
<input type="checkbox" id="terms_consent" name="terms_consent" required>
<label for="terms_consent">
Eu concordo explicitamente com os <a href="#" onclick="showTerms()">Termos de Serviço</a> e consinto com o processamento dos meus dados de acordo com a <a href="#" onclick="showPrivacy()">Política de Privacidade</a>.
</label>
</div>
Tem dúvidas sobre a sua configuração específica?
A nossa equipa trabalha com operadores de espaços, gestores de TI e engenheiros de rede em 80.000 locais. Agende uma chamada de 20 minutos e mostraremos como outros profissionais na sua situação o resolveram.
Modelo de CSS/HTML Customizado de Captive Portal
Abaixo está um modelo CSS/HTML de arquivo único, pronto para produção, que incorpora todas as melhores práticas de conformidade com CNA e prioridade para dispositivos móveis. Ele apresenta um layout responsivo, uma pilha de fontes do sistema, marcadores de posição de ativos prontos para Base64, entradas amigáveis ao toque e estruturas de consentimento explícitas em conformidade com a GDPR:
<!DOCTYPE html>
<html lang="pt-BR">
<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 responsivo do cartão */
.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;
}
/* Espaço reservado do logotipo Base64 incorporado */
.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;
}
/* Estilos do formulário */
.form-group {
text-align: left;
margin-bottom: 16px;
}
label {
display: block;
font-size: 14px;
font-weight: 600;
margin-bottom: 6px;
color: var(--color-dark);
}
/* Crítico: font-size precisa ser de pelo menos 16px para evitar o zoom automático do 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);
}
/* Estilos de consentimento */
.consent-group {
display: flex;
align-items: flex-start;
text-align: left;
margin: 20px 0;
}
/* Dimensionamento do destino compatível com toque */
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">SUA MARCA</text>
</svg>
</div>
<h1>Bem-vindo à WiFi de Visitantes</h1>
<p>Por favor, insira seus dados abaixo para obter acesso seguro à internet de alta velocidade.</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 Completo</label>
<input type="text" id="guest_name" name="name" placeholder="João Silva" required autocomplete="name">
</div>
<div class="form-group">
<label for="guest_email">Endereço de 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">
Eu aceito os <a href="#" onclick="toggleTerms(event)">Termos de Serviço</a> e concordo com o processamento de dados em conformidade com os regulamentos da GDPR.
</label>
</div>
<div id="terms_box" class="terms-scrollbox">
<strong>Termos de Serviço do WiFi:</strong><br>
1. Este serviço é fornecido no estado em que se encontra, sem garantias.<br>
2. Os usuários não devem se envolver em atividades ilegais de uso intensivo de largura de banda.<br>
3. Os dados pessoais são coletados exclusivamente para fins de autenticação e adesão de marketing, em conformidade com nossa Política de Privacidade.
</div>
<button type="submit" class="btn-submit">Conectar ao 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('Você deve aceitar os Termos de Serviço para se conectar.');
return false;
}
return true;
}
</script>
</body>
</html>
Solução de Problemas e Mitigação de Riscos
Ao implantar Captive Portals com codificação HTML/CSS personalizada, as equipes de operações de TI frequentemente encontram vários riscos operacionais graves:
1. O Loop de Aviso de Certificado SSL/TLS
Como os Captive Portals funcionam interceptando o tráfego, eles apresentam um conflito fundamental com a segurança web HTTPS moderna. Quando um usuário tenta visitar um site HTTPS (por exemplo, https://www.google.com) e o gateway tenta redirecionar esse tráfego para um Captive Portal HTTP, o navegador detecta uma divergência no certificado SSL e exibe um aviso de segurança crítico "Sua conexão não é privada".
- Mitigação: Nunca tente interceptar o tráfego HTTPS diretamente. Dependa inteiramente do assistente nativo de CNA do sistema operacional (que faz uma solicitação HTTP não criptografada para acionar o redirecionamento). Certifique-se de que o domínio do seu Captive Portal tenha um certificado SSL válido e publicamente confiável (por exemplo, Let's Encrypt ou DigiCert) e seja servido via HTTPS apenas após o redirecionamento HTTP inicial ter encaminhado com sucesso o usuário para o domínio do seu portal [2].
2. Falhas de Resolução de DNS (A Armadilha do Walled Garden)
Se a sua página HTML personalizada fizer referência a recursos externos - como um endpoint OAuth de login social (por exemplo, Facebook, Google) ou um gateway de pagamento - as solicitações de DNS para esses domínios falharão, a menos que estejam explicitamente na lista de permissões no Walled Garden do controlador de rede sem fio. Se um domínio estiver ausente da lista de permissões, o fluxo de login será interrompido, exibindo uma tela em branco.
- Mitigação: Mantenha uma lista de Walled Garden estrita e mínima. Se utilizar logins sociais, adicione à lista de permissões os domínios curinga específicos recomendados pelos provedores de identidade (por exemplo,
*.google.com,*.gstatic.com).
3. Vulnerabilidades de Limite de Tempo de Sessão e MAC Spoofing
Os Captive Portals padrão autenticam dispositivos com base em seus endereços MAC. No entanto, os sistemas operacionais móveis modernos (iOS 14+ e Android 10+) utilizam endereços MAC aleatórios (endereços de WiFi privados) por padrão, rotacionando-os periodicamente. Isso pode fazer com que os visitantes sejam solicitados repetidamente a se autenticarem novamente, destruindo a experiência do usuário [1].
- Mitigação: Implemente limites de tempo de sessão razoáveis (por exemplo, 24 horas) no servidor RADIUS para evitar sessões obsoletas e utilize padrões de autenticação modernos como Passpoint (Hotspot 2.0) ou WPA3-Enterprise para um onboarding seguro e simplificado que ignora completamente os Captive Portals baseados em MAC.
Relevância dos Produtos Purple: Construir vs. Comprar
Embora codificar uma única página HTML seja simples, hospedar, proteger e dimensionar uma infraestrutura de Captive Portal personalizada apresenta enormes obstáculos técnicos e de conformidade. A tabela abaixo compara as realidades operacionais e de engenharia de auto-hospedar um portal personalizado versus utilizar a plataforma empresarial gerenciada da Purple:
| Recurso / Requisito Operacional | Portal Personalizado Auto-Hospedado | Plataforma Purple Enterprise WiFi |
|---|---|---|
| Personalização de HTML/CSS | Codificação totalmente manual, upload de arquivos para APs individuais ou servidores web locais. | Editor de desenvolvedor pixel-perfect que permite injeções personalizadas de HTML/CSS, combinado com um construtor visual de arrastar e soltar. |
| Infraestrutura RADIUS | Deve implantar, configurar e manter servidores FreeRADIUS ou Cloud RADIUS de alta disponibilidade [4]. | RADIUS nativo em nuvem, distribuído globalmente e integrado com redundância ativo-ativo e SLAs de 99,99% de tempo de atividade. |
| Suporte a AP de Múltiplos Fabricantes | Scripts de integração personalizados necessários para cada fabricante de hardware (Cisco, Aruba, Meraki, Ruckus) [5]. | Integração nativa e pronta para uso com mais de 200 modelos de hardware; implantação unificada de portal em parques de hardware misto. |
| Privacidade de Dados e Conformidade | O estabelecimento assume 100% de responsabilidade legal pela conformidade com GDPR, CCPA e PCI-DSS, incluindo criptografia segura de banco de dados e fluxos de exclusão de dados. | Totalmente em conformidade por design. Gerenciamento de consentimento integrado, solicitações automatizadas de exclusão de titulares de dados e hospedagem segura com certificação ISO 27001. |
| Analytics & Marketing | Requires building custom data ingestion pipelines and integrating third-party marketing tools. | Enterprise-grade analytics dashboard with real-time footfall tracking, return-rate metrics, and automated marketing campaign triggers [6]. |
| Identity Provider Integrations | Manual OAuth2 integrations with Google, Facebook, Apple, and local SMS gateways. | One-click integrations with major social platforms, SMS gateways, and Azure AD / Okta for corporate guests. |
Purple's platform resolves the "Build vs. Buy" dilemma. It provides developers with the complete creative freedom of a custom HTML/CSS workspace while eliminating the complex, high-risk backend infrastructure engineering required to support secure RADIUS authentication at scale.
ROI & Business Impact
Investing in a professionally engineered, responsive custom captive portal delivers quantifiable returns across IT operations, marketing, and legal compliance.
1. Operational Cost Reduction (IT Helpdesk Tickets)
In large-scale deployments, such as a stadium or multi-site retail chain, a broken captive portal is a leading driver of IT helpdesk escalations. When guests encounter a "white screen" or a non-responsive login button, they overwhelm on-site staff or submit support tickets.
$$\text{Annual Support Savings} = (\text{Total Annual Guest Visits} \times \text{Portal Failure Rate} \times \text{Helpdesk Contact Rate}) \times \text{Cost Per Support Ticket}$$
- Scenario: A convention centre with 1,000,000 annual visitors. A poorly coded portal has a 5% failure rate on older iOS devices, leading to a 10% helpdesk contact rate. At an industry-standard $15 per support ticket, the operational cost is: $$(1,000,000 \times 0.05 \times 0.10) \times $15 = $75,000 \text{ annually in avoidable support overhead}$$
- Outcome: Transitioning to a CNA-optimised, mobile-first template reduces the portal failure rate to <0.1%, virtually eliminating this operational drain.
2. Marketing Data Capture and Opt-in Optimisation
For retail and hospitality venues, the guest WiFi portal is the primary mechanism for capturing clean, first-party customer data. A poorly designed user interface with microscopic text or a clunky form layout causes high bounce rates - users abandon the login process entirely, resulting in lost marketing opportunities.
- Case Study (Retail): A national retail chain implemented a mobile-first optimised captive portal utilising Purple's platform. By replacing a multi-step login form with a single-field email input (font-size: 16px) and an optimised 48px tap-target button, they saw a 42% increase in completed registrations and a 28% increase in marketing newsletter opt-ins within the first quarter [6].
3. Legal and Regulatory Risk Mitigation
Sob o GDPR e CCPA, a coleta de dados não em conformidade acarreta penalidades financeiras severas (até 4% do faturamento anual global sob o GDPR). Depender de caixas de seleção pré-marcadas ou deixar de fornecer uma Política de Privacidade clara e de fácil acesso em sua splash page expõe a empresa a uma imensa responsabilidade jurídica.
- ROI de mitigação: Implementar uma caixa de seleção de consentimento explícita e desmarcada e hospedar os termos em uma caixa de rolagem otimizada garante 100% de conformidade regulatória, mitigando o risco de multas regulatórias multimilionárias e protegendo a reputação da marca.
Resumo dos Principais Aprendizados
- O Sandbox do CNA é restritivo: O Websheet do iOS da Apple e o CNA do macOS são ambientes altamente isolados em sandbox que bloqueiam ativos externos, cookies e fontes da web. Toda a estilização e ativos devem ser independentes (CSS inline, imagens Base64, fontes do sistema) [1].
- AJAX quebra o handshake de saída do iOS: Para transferir com sucesso o dispositivo iOS de "cativo" para "conectado" (alterando o botão superior direito de "Cancelar" para "Concluído"), você deve acionar um redirecionamento HTTP de página inteira. Atualizações assíncronas de DOM deixarão o dispositivo em um loop cativo.
- Mobile-First é obrigatório: Mais de 90% dos logins ocorrem em dispositivos móveis. Desenvolva um layout de coluna única (largura máxima: 480px), utilize alvos de toque fáceis de usar (mínimo de 44px x 44px) e aplique um tamanho mínimo de fonte de 16px em todas as entradas de texto para evitar o zoom automático do navegador do iOS.
- As Walled Gardens controlam o DNS: Qualquer domínio externo referenciado durante o login (por exemplo, APIs de login social) deve ser explicitamente incluído na lista de permissões da walled garden do controlador sem fio, caso contrário, a página não será carregada.
- Purple elimina a complexidade do backend: Utilizar o construtor de portal da Purple oferece aos desenvolvedores controle total de HTML/CSS por meio de um editor personalizado, enquanto elimina os imensos encargos de segurança, escalabilidade e conformidade de RADIUS, integrações de AP multi-vendor e gerenciamento de banco de dados em conformidade com o GDPR [3].
Referências
- [1] Wireless Broadband Alliance: Captive Network Portal Behaviour
- [2] Android Open Source Project: Captive Portal Login Webview Integration
- [3] European Data Protection Board: Guidelines on Consent under Regulation 2016/679
- [4] How to Implement 802.1X Authentication with Cloud RADIUS
- [5] Cisco Wireless APs: 2026 Guide to Products & Deployment
- [6] Purple WiFi Marketing & Analytics Platform
Ouça o Briefing Técnico
Ouça um arquiteto de soluções sênior discutir as restrições técnicas e estratégias de implementação para Captive Portals personalizados:
Definições principais
Captive Portal
Uma página web que é exibida para usuários recém-conectados de uma rede WiFi antes de receberem acesso mais amplo aos recursos da rede, normalmente usada para autenticação, pagamento ou exibição de termos de serviço.
As equipes de TI implantam Captive Portals no nível do gateway para controlar o acesso de convidados, capturar dados de usuários e garantir a conformidade legal.
Captive Network Assistant (CNA)
Um mini-navegador altamente restrito e isolado em sandbox, gerado automaticamente pelos sistemas operacionais (como Apple iOS e macOS) ao detectar um redirecionamento de rede cativa, projetado exclusivamente para facilitar a autenticação no portal.
As webviews do CNA impõem limitações estritas, incluindo o bloqueio de CDNs externas, cookies persistentes e armazenamento local, o que frequentemente quebra designs de web padrão.
Walled Garden
Uma lista restrita de endereços IP, sub-redes ou nomes de domínio que um usuário convidado não autenticado tem permissão para acessar através do gateway antes de concluir o processo de login do Captive Portal.
Os desenvolvedores devem garantir que qualquer recurso externo (como APIs de login social ou gateways de pagamento) esteja incluído na lista de permissões do Walled Garden para evitar que o fluxo de login trave.
Codificação Base64
Um esquema de codificação binário para texto que representa dados binários (como imagens) como uma string ASCII, permitindo que os recursos sejam incorporados diretamente em documentos HTML ou CSS.
A utilização da codificação Base64 para logotipos e ícones elimina solicitações HTTP externas, garantindo que os elementos visuais sejam renderizados perfeitamente em ambientes CNA offline.
RADIUS (Remote Authentication Dial-In User Service)
Um protocolo de rede que fornece gerenciamento centralizado de Autenticação, Autorização e Contabilização (AAA) para usuários que se conectam e utilizam um serviço de rede.
O servidor do Captive Portal se comunica com um servidor RADIUS para autorizar o endereço MAC do convidado no gateway de rede assim que os critérios de autenticação forem atendidos.
System Font Stack
Uma declaração CSS font-family que prioriza fontes pré-instaladas do sistema operacional (como San Francisco no iOS, Segoe UI no Windows e Roboto no Android) em vez de fontes da web externas.
A implementação de uma system font stack garante a renderização imediata da tipografia sem disparar solicitações HTTP externas bloqueadas para serviços como o Google Fonts.
Canary URL
Uma URL HTTP dedicada e não criptografada mantida por fornecedores de sistemas operacionais (por exemplo, captive.apple.com) para testar se um dispositivo possui conectividade irrestrita à internet.
O gerenciador de rede em segundo plano do sistema operacional verifica esta URL para detectar a presença de um Captive Portal e acionar o popup do webview do CNA.
Passpoint (Hotspot 2.0)
Um padrão do setor desenvolvido pela WiFi Alliance que permite que dispositivos móveis descubram e se autentiquem automaticamente e com segurança em hotspots WiFi, ignorando logins manuais em Captive Portals.
As empresas utilizam o Passpoint em conjunto com plataformas como o Purple para fazer a transição dos visitantes de páginas de login com alto atrito para experiências de roaming seguras e contínuas, semelhantes às de redes celulares.
Exemplos práticos
Uma rede de hotéis de luxo de 250 quartos [Hospitality](/industries/hotels) deseja implementar uma página de login de WiFi para visitantes personalizada que corresponda perfeitamente às diretrizes de sua marca premium. Sua agência criativa projetou uma splash page utilizando tipografia personalizada da marca (hospedada no Adobe Fonts), várias imagens de fundo de alta resolução (hospedadas em um bucket público AWS S3) e um assistente JavaScript animado de várias etapas. Quando implantado, os visitantes com iOS conectam-se ao SSID, mas o portal aparece como uma tela branca em branco e os usuários não conseguem se autenticar.
Para resolver a tela em branco e a identidade visual quebrada, devemos reestruturar a arquitetura frontend do portal para cumprir as restrições de sandbox do Apple CNA:
- Remediação de Tipografia: Como o Adobe Fonts requer uma requisição HTTP externa que é bloqueada pelo CNA, substituímos a chamada de fonte personalizada por uma pilha de fontes nativas de sistema premium (
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;). Isso garante a renderização instantânea sem chamadas de rede externas. - Otimização de Ativos: As imagens de fundo no AWS S3 estão bloqueadas porque o S3 não está no walled garden do gateway. Compactamos o logotipo principal da marca, convertemos para um SVG leve e o codificamos diretamente no HTML como uma Data URI Base64. Para o fundo, substituímos as imagens pesadas por um gradiente CSS limpo e responsivo usando as cores da marca do hotel, reduzindo significativamente o peso da página.
- Simplificação de JavaScript: O assistente animado de várias etapas depende de bibliotecas externas jQuery e GSAP. Removemos essas dependências externas e refatoramos o formulário em uma estrutura HTML de página única e coluna única. A validação do formulário é reescrita em JavaScript vanilla leve.
- Handshake de Autenticação: O envio do formulário é modificado de um envio baseado em AJAX para um
<form action="/submit" method="POST">HTML nativo para acionar um redirecionamento de página inteira, permitindo que o Websheet do iOS execute sua verificação de teste e exiba o botão "Concluído".
Uma rede de varejo nacional [Retail](/industries/retail) com 450 lojas deseja capturar e-mails de visitantes por meio de splash pages de WiFi para alimentar seu CRM. Eles exigem que os visitantes optem por receber newsletters de marketing. O design inicial tem uma caixa de seleção pré-marcada "Concordo em receber e-mails de marketing". Além disso, o portal está hospedado em um único servidor local em sua sede. Durante os horários de pico (sábado à tarde), os visitantes de todo o país enfrentam atrasos graves e muitos não conseguem carregar a página de login, resultando em uma queda massiva nas taxas de captura de dados.
Devemos abordar tanto a violação de conformidade quanto o gargalo de infraestrutura:
- Remediação de Conformidade: Sob o GDPR e CCPA, caixas de consentimento pré-selecionadas são ilegais. Modificamos o HTML para tornar a caixa de seleção de consentimento de marketing desmarcada por padrão (
<input type="checkbox" id="marketing_consent">). Também adicionamos uma caixa de seleção separada e obrigatória para os Termos de Serviço para desvincular o acordo legal do opt-in de marketing. - Escalonamento de Infraestrutura: Hospedar um Captive Portal nacional em um único servidor centralizado cria um ponto único de falha e um enorme gargalo de latência. Migramos o frontend do portal para uma rede de distribuição de conteúdo (CDN) globalmente distribuída e de alta disponibilidade com cache de borda.
- Integração RADIUS: Configuramos os pontos de acesso das lojas locais para apontar para um cluster RADIUS nativo em nuvem com redundância ativo-ativo, garantindo que as solicitações de autenticação sejam processadas localmente na borda com latência abaixo de 50ms, mesmo durante o pico de tráfego de sábado.
- Migração para o Purple: Para eliminar todo esse esforço de engenharia, o varejista migra para o Purple. As ferramentas de consentimento em conformidade com o GDPR integradas do Purple gerenciam automaticamente os opt-ins em conformidade, e sua infraestrutura em nuvem distribuída globalmente lida com milhões de autenticações diárias com 99,99% de uptime, resolvendo completamente o gargalo de escala.
Questões práticas
Q1. Uma equipe de TI em um grande aeroporto internacional [Transport](/industries/trains) implanta um Captive Portal com código personalizado. Eles percebem que, embora os usuários de Android se conectem perfeitamente, uma parte significativa dos usuários de iOS enfrenta um problema em que se autenticam com sucesso, mas não conseguem navegar na web. Em uma inspeção mais detalhada, os dispositivos iOS mostram que estão conectados ao SSID, mas o botão superior direito no popup do portal ainda diz "Cancelar" em vez de "Concluído". Qual é a causa raiz desse problema e como o desenvolvedor deve corrigi-lo?
Dica: Analise como o assistente do Apple CNA detecta que uma rede passou do estado cativo para autenticado e qual ação do navegador é necessária para acionar essa verificação.
Ver resposta modelo
A causa raiz é que a página de sucesso do portal está atualizando a interface do usuário dinamicamente via JavaScript (roteamento AJAX/SPA) em vez de realizar uma navegação HTTP de página inteira. O mini-navegador do Apple iOS Captive Network Assistant (CNA) só executa novamente sua verificação de conectividade em segundo plano (a requisição canário para captive.apple.com) quando ocorre um redirecionamento ou navegação de página inteira. Se o desenvolvedor enviar o formulário de login via AJAX e simplesmente exibir uma mensagem de "Sucesso" no DOM, o CNA continuará sem saber que a rede foi liberada. Consequentemente, o botão superior direito permanece como "Cancelar". Se o usuário clicar em "Cancelar" para sair, o sistema operacional assume que o login falhou e se desconecta da rede WiFi.
Solução: O desenvolvedor deve modificar o manipulador de sucesso de autenticação para forçar um redirecionamento de página inteira. Isso pode ser feito enviando o formulário de login nativamente por meio de um <form action="/submit" method="POST"> padrão do HTML ou executando window.location.href = '/success_landing_page' em JavaScript assim que a API retornar uma resposta de autenticação bem-sucedida. Isso aciona o carregamento de página inteira necessário, forçando o assistente do CNA a reavaliar o estado da rede, verificar se a Canary URL agora está acessível e alterar o botão superior direito para "Concluído".
Q2. Uma equipe de operações de estádio [Events] deseja lançar uma rede WiFi para convidados que capture opt-ins de marketing. O responsável pela conformidade insiste que o portal deve ser 100% em conformidade com o GDPR. A equipe de desenvolvimento apresenta um protótipo onde o formulário de login tem uma caixa pré-marcada que diz "Eu concordo com os Termos de Serviço e autorizo o envio de newsletters de marketing". Por que esse design não está em conformidade e como a estrutura do formulário e o HTML/CSS devem ser refatorados para atender ao GDPR e, ao mesmo tempo, manter uma alta taxa de conversão?
Dica: Considere as exigências rigorosas do GDPR em relação ao consentimento explícito, a separação dos opt-ins de marketing dos termos de serviço e a visibilidade física dos textos legais em telas de dispositivos móveis.
Ver resposta modelo
O design proposto viola o GDPR em duas frentes principais: primeiro, caixas de seleção pré-assinaladas não constituem consentimento válido, que deve ser livremente fornecido, específico, informado e inequívoco. Segundo, vincular o consentimento de marketing ao acordo com os Termos de Serviço não está em conformidade; um usuário não pode ser forçado a aceitar e-mails de marketing como condição para usar o serviço de WiFi.
Estratégia de Refatoração:
- Desacoplar o Consentimento: Divida a caixa de seleção em duas caixas de seleção distintas. A Caixa de Seleção A é obrigatória e cobre os Termos de Serviço e a Política de Privacidade. A Caixa de Seleção B é opcional e cobre a adesão ao boletim informativo de marketing.
- Definir como Desmarcado: Garanta que ambas as caixas de seleção estejam desmarcadas por padrão no HTML (atributo
checkedomitido). - Visibilidade por CSS: Como mais de 90% dos usuários estão no celular, posicione as caixas de seleção diretamente acima do botão 'Conectar' para que fiquem visíveis 'above the fold' sem necessidade de rolagem. Use um conjunto de fontes do sistema e defina o tamanho da fonte do rótulo para 14px com uma altura de linha de 1.4 para melhor legibilidade.
- Caixa de Rolagem dos Termos: Para evitar que o texto legal empurre os elementos do formulário para fora da tela, coloque os Termos de Serviço detalhados em um contêiner rolável com altura fixa (
max-height: 100px; overflow-y: auto; background-color: #F5F1ED; border: 1px solid #D1D5DB; border-radius: 6px;) que pode ser aberto ou fechado por meio de um link de texto. Isso mantém um layout limpo e de alta conversão, garantindo conformidade legal absoluta.
Q3. Uma rede de varejo [Retail](/industries/retail) está implantando uma splash page com código personalizado em 100 lojas. O designer usou Google Fonts (Montserrat) e vinculou a uma folha de estilo Bootstrap hospedada em CDN no cabeçalho HTML. Durante os testes em uma rede corporativa, a página é renderizada perfeitamente. No entanto, quando implantada no AP de uma loja de testes com uma configuração de rede cativa, a página é renderizada com texto em Times New Roman sem estilização, alinhamento quebrado e ícones ausentes. Por que isso acontece e como os ativos devem ser refatorados?
Dica: Analise o estado da conexão de rede antes que um usuário seja autenticado e determine como o navegador lida com requisições HTTP externas para domínios fora do jardim murado (walled garden).
Ver resposta modelo
Essa falha ocorre porque o dispositivo está em um estado cativo não autenticado quando a splash page é carregada. Nesse estado, o gateway sem fio bloqueia todo o tráfego de internet de saída, permitindo requisições apenas para domínios explicitamente incluídos na lista de permissões do Walled Garden do gateway. Como os domínios de CDN para o Bootstrap (cdn.jsdelivr.net) e Google Fonts (fonts.googleapis.com) não estão na lista de permissões, as requisições do navegador para buscar a folha de estilo e os arquivos de fonte falham silenciosamente. Consequentemente, o navegador recorre ao seu mecanismo de renderização padrão, resultando em HTML sem estilização (texto em Times New Roman) e layouts quebrados.
Estratégia de Refatoração:
- CSS Inline: Remova o link da folha de estilo Bootstrap externa. Copie as regras necessárias de CSS grid/flexbox diretamente em um bloco
<style>no<head>do HTML. Isso garante que todas as instruções de layout sejam entregues no payload inicial de página única. - Implementar Conjunto de Fontes do Sistema: Remova a chamada
@importou<link>do Google Fonts. Substitua-a por um conjunto nativo de fontes do sistema no CSS (font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;). Isso força o dispositivo a usar fontes de alta qualidade já pré-instaladas no sistema operacional, eliminando totalmente a dependência de rede externa. - Codificar Ícones/Logotipos em Base64: Se o layout depender de imagens externas ou bibliotecas de ícones (como FontAwesome), converta esses ícones para o formato SVG e incorpore-os inline no HTML ou como URIs de Dados Base64 no CSS. Isso garante que a página seja 100% autônoma e renderize perfeitamente mesmo sem nenhuma conectividade com a internet.
Perguntas frequentes
O que é o Captive Network Assistant (CNA) e por que o HTML e CSS de um Captive Portal personalizado se comportam de maneira diferente nele?
O Captive Network Assistant (CNA) é uma webview restrita e isolada (sandbox) aberta automaticamente por sistemas operacionais como iOS, macOS, Android e Windows ao detectar a interceptação de rede. Os CNAs carecem de recursos completos de navegador: eles frequentemente bloqueiam popups, restringem o armazenamento persistente de cookies, limitam a velocidade de execução do JavaScript, desativam downloads de arquivos e impõem limites rígidos de viewport. O HTML e CSS de um Captive Portal personalizado devem ser leves, independentes e evitar redirecionamentos externos que possam encerrar a sessão do CNA prematuramente.
Quais domínios e endereços IP devem ser incluídos em um walled garden de Captive Portal?
Um walled garden (lista de permissões de pré-autenticação) permite que clientes sem fio não autenticados alcancem recursos críticos antes de fazer o login. Você deve incluir os nomes de host para quaisquer folhas de estilo CSS hospedadas externamente, pacotes JavaScript, fontes da web ou recursos de CDN usados na página de login. Se houver suporte para login social ou verificação por SMS, você também deve incluir na lista de permissões os endpoints de autenticação da Apple, Google ou gateways de SMS, bem como o redirecionamento do controlador e os endpoints da API RFC 8908.
Como as normas RFC 8908 e RFC 8910 modernizam a descoberta de Captive Portals em comparação ao redirecionamento HTTP legado?
Os Captive Portals tradicionais interceptam requisições HTTP em texto simples (porta 80) e retornam um redirecionamento HTTP 302, o que causa avisos de certificado SSL/TLS se o cliente tentar uma conexão HTTPS. As normas RFC 8908 e RFC 8910 estabelecem uma API de Captive Portal padronizada onde a rede sem fio anuncia uma URL de API via DHCP Option 114 ou IPv6 Router Advertisement Option 38. O sistema operacional do cliente consulta esse endpoint JSON diretamente, recebendo o status cativo explícito, os termos do local e as URLs de autenticação sem adulteração de pacotes ou erros de certificado.
Quais padrões de design CSS funcionam melhor para splash pages de captive portal em dispositivos móveis?
As melhores práticas de CSS para captive portal incluem o uso de layouts fluidos com Flexbox ou CSS Grid, definição de alvos de toque interativos de pelo menos 48x48 pixels para ergonomia de toque, uso de pilhas de fontes do sistema (como -apple-system, BlinkMacSystemFont, Segoe UI) para evitar downloads de webfonts que bloqueiam a renderização, incorporação em linha (inline) de ícones SVG críticos para minimizar requisições HTTP e especificação de uma tag meta viewport móvel estrita (width=device-width, initial-scale=1) para evitar rolagem horizontal incômoda dentro de mini-navegadores.
Como o Purple simplifica a implantação de captive portal personalizado e o gerenciamento de walled gardens?
O Purple substitui servidores web auto-hospedados frágeis por uma plataforma de captive portal em nuvem empresarial. O Purple oferece ferramentas de branding dinâmico, orquestração automatizada de walled gardens em Cisco Meraki, HPE Aruba, Ruckus, Ubiquiti UniFi e Fortinet, suporte total ao padrão RFC 8908 e testes rigorosos de compatibilidade em webviews CNA de iOS e Android, com o respaldo de 99,99% de tempo de atividade na nuvem e integrações de marketing de CRM.
Continue a ler esta série
Portal de convidados Ubiquiti UniFi não redirecionando: causas e correções
Este guia isola uma falha de redirecionamento do portal de convidados UniFi seguindo a sequência do status do convidado, redirecionamento, rota de pré-autorização e autorização do controlador. Ele oferece às equipes de TI do local um método fundamentado para lidar com a confusão entre rede de convidados e Hotspot, redirecionamentos para portais externos, requisitos atuais de conta do UniFi OS e testes de isolamento de DNS.
Cisco Meraki splash page não está funcionando: um fluxograma de diagnóstico
Este guia prático de dia dois isola onde um fluxo de splash do Cisco Meraki falhou: autorização do cliente, início do redirecionamento HTTP, acessibilidade do walled-garden ou sign-on RADIUS. Ele oferece às equipes de TI do local um caminho controlado de evidências para restaurar o Guest WiFi sem fazer alterações amplas em um ambiente de produção.
Guia de Configuração de WiFi para Visitantes Corporativos: Segmentação por VLAN, Segurança e Portais Captivos
Este guia técnico mostra às equipes de TI como configurar o WiFi para Visitantes como um serviço de acesso à internet controlado, usando segmentação por VLAN, política de firewall e um Captive Portal. Ele também explica como os formulários de registro e controles de integração do Purple oferecem suporte a uma experiência de visitante proporcional, sem enfraquecer o limite em torno dos sistemas operacionais, de pagamento e da equipe.
Tem dúvidas sobre a sua configuração específica?
A nossa equipa trabalha com operadores de espaços, gestores de TI e engenheiros de rede em 80.000 locais. Agende uma chamada de 20 minutos e mostraremos como outros profissionais na sua situação o resolveram.