O armazenamento no navegador permite que aplicações web mantenham dados do lado do cliente, melhorando a experiência do usuário e reduzindo requisições ao servidor. Nesta aula, vamos detalhar os mecanismos localStorage, sessionStorage e cookies, entendendo quando e como utilizá-los, além de suas limitações e cuidados de segurança.

Com o avanço das aplicações web modernas, a capacidade de persistir dados localmente se tornou essencial. Seja para salvar preferências do usuário, manter sessões ou armazenar dados temporários, cada técnica possui características específicas que influenciam a escolha do desenvolvedor.

localStorage e sessionStorage

Tanto localStorage quanto sessionStorage são objetos da Web Storage API que permitem armazenar pares chave-valor de forma simples e síncrona. A principal diferença está no ciclo de vida: localStorage persiste mesmo após o fechamento do navegador, enquanto sessionStorage é limpo ao finalizar a sessão (quando a aba ou janela é fechada).

Ambos oferecem uma interface similar com métodos como setItem, getItem, removeItem e clear. Os dados são armazenados como strings, sendo necessário converter objetos com JSON.stringify e JSON.parse.

// localStorage: dados persistem mesmo após fechar o navegador
localStorage.setItem('tema', 'escuro');
const tema = localStorage.getItem('tema');
console.log(tema); // 'escuro'

// sessionStorage: dados são removidos ao fechar a aba
sessionStorage.setItem('sessao', 'ativa');
const sessao = sessionStorage.getItem('sessao');
console.log(sessao); // 'ativa'

// Armazenando objetos
const usuario = { nome: 'João', id: 123 };
localStorage.setItem('usuario', JSON.stringify(usuario));
const usuarioRecuperado = JSON.parse(localStorage.getItem('usuario'));
console.log(usuarioRecuperado.nome); // 'João'

// Removendo um item
localStorage.removeItem('tema');

// Limpando todo o storage
sessionStorage.clear();

É importante notar que ambos os storages são específicos por origem (protocolo + domínio + porta) e não são enviados ao servidor automaticamente. Eles são ideais para dados que não precisam ser transmitidos em cada requisição, como preferências de interface ou tokens de autenticação (com cuidado).

Cookies (introdução)

Cookies são pequenos arquivos de texto armazenados no navegador, enviados automaticamente ao servidor em cada requisição HTTP para o domínio que os criou. Eles são frequentemente usados para gerenciar sessões, rastrear usuários e armazenar preferências que precisam ser compartilhadas com o servidor.

Em JavaScript, os cookies podem ser acessados e modificados através da propriedade document.cookie. Diferente do Web Storage, os cookies têm um limite de tamanho pequeno (cerca de 4KB por cookie) e podem ser configurados com atributos como expires, path, domain, secure e SameSite.

// Definindo um cookie que expira em 7 dias
const dataExpiracao = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toUTCString();
document.cookie = `sessao=abc123; expires=${dataExpiracao}; path=/; SameSite=Lax`;

// Lendo todos os cookies (string com pares separados por ponto e vírgula)
console.log(document.cookie); // "sessao=abc123; outro=valor"

// Função para obter valor de um cookie específico
function getCookie(nome) {
  const cookies = document.cookie.split('; ');
  for (let cookie of cookies) {
    const [chave, valor] = cookie.split('=');
    if (chave === nome) return decodeURIComponent(valor);
  }
  return null;
}
console.log(getCookie('sessao')); // 'abc123'

// Removendo um cookie (definindo data passada)
document.cookie = 'sessao=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';

Cookies são enviados em todas as requisições ao domínio, o que pode impactar a performance. Além disso, por serem armazenados como texto, são vulneráveis a ataques como XSS (Cross-Site Scripting) se não forem devidamente protegidos com flags HttpOnly e Secure. A flag HttpOnly impede o acesso via JavaScript, reduzindo o risco de roubo de sessão.

Limites e segurança

Cada mecanismo de armazenamento possui limites de capacidade que devem ser considerados. Para localStorage e sessionStorage, o limite varia entre 5MB e 10MB por origem na maioria dos navegadores. Já os cookies têm limite de 4KB por cookie e um máximo de cerca de 50 cookies por domínio (especificação varia).

Em termos de segurança, o Web Storage não é enviado automaticamente ao servidor, o que reduz exposição em requisições. No entanto, ambos os storages são acessíveis via JavaScript, tornando-os vulneráveis a ataques XSS. Dados sensíveis como senhas ou tokens de autenticação devem ser armazenados preferencialmente em cookies com HttpOnly e Secure, ou em memória volátil. Além disso, o localStorage não expira, o que pode ser um problema se um dispositivo compartilhado for usado.

Boas práticas incluem: nunca armazenar informações críticas em localStorage ou sessionStorage sem criptografia; usar cookies com flags de segurança para dados de sessão; e considerar o uso de IndexedDB para grandes volumes de dados estruturados. Sempre validar e sanitizar dados antes de armazenar, especialmente se originados de entrada do usuário.

Referências

Exercícios

  1. Exercício 1: Crie uma função que salve no localStorage um objeto representando as configurações de tema (com propriedades: corFundo, corTexto, tamanhoFonte). Em seguida, crie outra função que recupere e aplique essas configurações ao document.body. Teste no console.

    ✓ Resposta:
    function salvarConfig(tema) {
      localStorage.setItem('configTema', JSON.stringify(tema));
    }
    
    function aplicarConfig() {
      const config = JSON.parse(localStorage.getItem('configTema'));
      if (config) {
        document.body.style.backgroundColor = config.corFundo;
        document.body.style.color = config.corTexto;
        document.body.style.fontSize = config.tamanhoFonte;
      }
    }
    
    // Exemplo de uso:
    salvarConfig({ corFundo: '#333', corTexto: '#fff', tamanhoFonte: '16px' });
    aplicarConfig();
  2. Exercício 2: Escreva um código que armazene um contador de visitas no sessionStorage. Cada vez que a página for recarregada (simule com console.log), o contador deve ser incrementado. Mostre o valor atual no console.

    ✓ Resposta:
    function incrementarContador() {
      let contador = parseInt(sessionStorage.getItem('contadorVisitas')) || 0;
      contador++;
      sessionStorage.setItem('contadorVisitas', contador);
      console.log('Visita número:', contador);
    }
    
    // Chame a função sempre que a página carregar
    incrementarContador();
  3. Exercício 3: Crie uma função que defina um cookie chamado 'ultimaVisita' com a data e hora atuais (use new Date().toISOString()) e que expire em 1 hora. Em seguida, leia o cookie e exiba no console.

    ✓ Resposta:
    function definirCookieUltimaVisita() {
      const agora = new Date();
      const expira = new Date(agora.getTime() + 60 * 60 * 1000); // 1 hora
      document.cookie = `ultimaVisita=${agora.toISOString()}; expires=${expira.toUTCString()}; path=/`;
    }
    
    function lerCookieUltimaVisita() {
      const cookies = document.cookie.split('; ');
      for (let cookie of cookies) {
        const [nome, valor] = cookie.split('=');
        if (nome === 'ultimaVisita') {
          console.log('Última visita:', decodeURIComponent(valor));
          return;
        }
      }
      console.log('Cookie não encontrado.');
    }
    
    definirCookieUltimaVisita();
    lerCookieUltimaVisita();
  4. Exercício 4: Explique a diferença entre localStorage e sessionStorage em termos de persistência e escopo. Dê um exemplo de uso adequado para cada um.

    ✓ Resposta: localStorage persiste os dados mesmo após o navegador ser fechado, sendo útil para preferências do usuário que devem ser lembradas entre sessões, como tema escuro. sessionStorage mantém os dados apenas durante a sessão da aba/janela, sendo ideal para informações temporárias como estado de um formulário em preenchimento, que devem ser perdidas ao fechar a aba.
  5. Exercício 5: Quais são as principais diferenças de segurança entre cookies e Web Storage? Por que cookies com a flag HttpOnly são mais seguros para armazenar tokens de autenticação?

    ✓ Resposta: Cookies são enviados automaticamente ao servidor em cada requisição, o que pode expor dados se a conexão não for segura, mas permitem flags como HttpOnly (impede acesso via JavaScript) e Secure (envia apenas sobre HTTPS). Web Storage não é enviado ao servidor automaticamente, reduzindo exposição em trânsito, mas é totalmente acessível por JavaScript, tornando-o vulnerável a XSS. Tokens de autenticação armazenados em cookies com HttpOnly são mais seguros porque mesmo que um ataque XSS ocorra, o invasor não consegue ler o token via JavaScript, protegendo a sessão.