O que resulta em uma boa experiência de logout?

Kenji Baheux
Kenji Baheux

Saída

Quando um usuário sai de um site, ele comunica o desejo de sair completamente de uma experiência personalizada. Portanto, é importante aderir o mais próximo possível ao modelo mental do usuário. Por exemplo, uma experiência de desativação adequada também precisa levar em conta as guias que o usuário pode ter aberto antes de decidir sair.

A chave para uma ótima experiência de encerramento de sessão pode ser resumida em consistência nos aspectos visuais e de estado da experiência do usuário. Este guia oferece conselhos concretos sobre o que prestar atenção e como ter uma boa experiência de desativação.

Principais considerações

Ao implementar a funcionalidade de desativação da conta no seu site, preste atenção nos seguintes aspectos para garantir um processo de desativação tranquilo, seguro e intuitivo:

  • UX de desativação clara e consistente: forneça um botão ou link de desativação claro e consistente, que seja facilmente identificável e acessível em todo o site. Evite usar rótulos ambíguos ou ocultar a funcionalidade de desativação em menus obscuros, páginas secundárias ou outros locais não intuitivos.
  • Solicitação de confirmação: implemente uma solicitação de confirmação antes de finalizar o processo de encerramento de sessão. Isso pode ajudar a evitar que os usuários saiam do serviço acidentalmente e permite que eles reconsiderem se realmente precisam sair. Por exemplo, se eles bloquearem o dispositivo com uma senha forte ou outro mecanismo de autenticação.
  • Processar várias guias: se um usuário abriu várias páginas do mesmo site em guias diferentes, verifique se o desligamento de uma guia também atualiza todas as outras guias abertas desse site.
  • Redirecionar para uma página de destino segura: após o logout, redirecione o usuário para uma página de destino segura que indique claramente que ele não está mais conectado. Evite redirecionar os usuários para páginas com informações personalizadas. Da mesma forma, verifique se outras guias não refletem mais um estado de login. Além disso, não crie um redirecionamento aberto que possa ser aproveitado por invasores.
  • Limpeza de sessão: depois que um usuário sai da sessão, remova completamente todos os dados sensíveis da sessão, cookies ou arquivos temporários associados à sessão do usuário. Isso impede o acesso não autorizado às informações do usuário ou à atividade da conta e também impede que o navegador restaure páginas com informações sensíveis dos vários caches, em particular o cache de navegação.
  • Tratamento de erros e feedback: forneça mensagens de erro claras ou feedback aos usuários se houver algum problema ao sair. Informe sobre possíveis riscos de segurança ou vazamentos de dados se o processo de desativação falhar.
  • Considerações de acessibilidade: verifique se o mecanismo de desativação da conta está acessível a usuários com deficiência, incluindo aqueles que usam tecnologias adaptativas, como leitores de tela ou navegação por teclado.
  • Compatibilidade com vários navegadores: teste a funcionalidade de logout em diferentes navegadores e dispositivos para garantir que ela funcione de forma consistente e confiável.
  • Monitoramento e atualizações contínuas: monitore regularmente o processo de desativação para detectar possíveis vulnerabilidades ou falhas de segurança. Implemente atualizações e patches em tempo hábil para resolver os problemas identificados.
  • Federação de identidade: se o usuário fez login usando uma identidade federada, verifique se o logout do provedor de identidade também é compatível e necessário. Além disso, se o provedor de identidade oferecer suporte ao login automático, impeça esse recurso.

O que fazer

  • Se você invalidar um cookie no servidor como parte de um fluxo de desativação (ou outros fluxos de revogação de acesso), exclua o cookie no dispositivo do usuário também.
  • Limpe todos os dados sensíveis que você armazenou no dispositivo do usuário: cookies, localStorage, sessionStorage, indexedDB, CacheStorage e qualquer outra loja de dados local.
  • Verifique se todos os recursos que contêm dados sensíveis, principalmente documentos HTML, são retornados com o cabeçalho HTTP Cache-control: no-store para que o navegador não os armazene em armazenamento permanente (por exemplo, no disco). Da mesma forma, as chamadas XHR/fetch que retornam dados sensíveis também precisam definir o cabeçalho HTTP Cache-Control: no-store para evitar o armazenamento em cache.
  • Verifique se todas as guias abertas no dispositivo do usuário estão atualizadas com as revogações de acesso no lado do servidor.

Limpar dados sensíveis ao sair

Ao sair, considere limpar dados sensíveis temporários e armazenados localmente. O foco em dados sensíveis é motivado pelo fato de que limpar tudo resultaria em uma experiência do usuário significativamente pior, porque esse usuário pode muito bem voltar. Por exemplo, se você limpar todos os dados armazenados localmente, os usuários vão precisar aceitar novamente os avisos de consentimento de cookies e passar por outros processos como se nunca tivessem acessado seu site.

Como limpar cookies

Na resposta da página que confirma o status de desativação, anexe cabeçalhos HTTP Set-Cookie para limpar todos os cookies relacionados ou que contenham dados sensíveis. Defina o valor de expires como uma data no passado distante e defina o valor do cookie como uma string vazia.

Set-Cookie: sensitivecookie1=; expires=Thu, 01 Jan 1970 00:00:00 GMT; secure
Set-Cookie: sensitivecookie2=; expires=Thu, 01 Jan 1970 00:00:00 GMT; secure
...

Cenário off-line

Embora a abordagem descrita acima seja suficiente para casos de uso gerais, ela não funciona se o usuário estiver trabalhando off-line. Talvez seja necessário exigir dois cookies para acompanhar o estado de login: um cookie seguro somente HTTPS e um cookie normal acessível por JavaScript. Se o usuário estiver tentando sair enquanto estiver off-line, limpe o cookie do JavaScript e prossiga com outras operações de limpeza, se possível. Se você tiver um worker de serviço, também poderá aproveitar a API Background Fetch para tentar novamente uma solicitação para limpar o estado no servidor quando o usuário estiver on-line mais tarde.

Como limpar o armazenamento

Na resposta da página que confirma o estado de desativação, limpe os dados sensíveis de vários repositórios de dados:

  • sessionStorage: embora seja apagado quando o usuário encerra a sessão no seu site, é recomendável limpar proativamente os dados sensíveis quando o usuário sair, caso ele se esqueça de fechar todas as guias abertas no seu site.

    // Remove sensitive data from sessionStorage
    sessionStorage.removeItem('sensitiveSessionData1');
    // ...
    
    // Or if everything in sessionStorage is sensitive, clear it all
    sessionStorage.clear();
    
  • localStorage, indexedDB, Cache/APIs Service Worker: quando o usuário sair, limpe todos os dados sensíveis que você armazenou usando essas APIs, já que esses dados persistem em todas as sessões.

    // Remove sensitive data from localStorage:
    localStorage.removeItem('sensitiveData1');
    // ...
    
    // Or if everything in localStorage is sensitive, clear it all:
    localStorage.clear();
    
    // Delete sensitive object stores in indexedDB:
    const name = 'exampleDB';
    const version = 1;
    const request = indexedDB.open(name, version);
    
    request.onsuccess = (event) => {
      const db = request.result;
      db.deleteObjectStore('sensitiveStore1');
      db.deleteObjectStore('sensitiveStore2');
    
      // ...
    
      db.close();
    }
    
    // Delete sensitive resources stored via the Cache API:
    caches.open('cacheV1').then((cache) => {
      await cache.delete("/personal/profile.png");
    
      // ...
    }
    
    // Or better yet, clear a cache bucket that contains sensitive resources:
    caches.delete('personalizedV1');
    

Como limpar caches

  • Cache HTTP: se você definir Cache-control: no-store em recursos com dados sensíveis, o cache HTTP não reterá nada sensível.
  • Cache de ida/volta: da mesma forma, se você seguiu as recomendações sobre Cache-control: no-store e sobre a exclusão de cookies sensíveis (por exemplo, cookies seguros somente HTTPS relacionados à autenticação) quando os usuários saem da conta, não precisa se preocupar com a retenção de dados sensíveis no cache de ida/volta. O recurso de cache de avanço e retorno remove as páginas de mesma origem exibidas com um cabeçalho HTTP Cache-control: no-store se observar um ou mais dos seguintes indicadores:
    • Um ou mais cookies seguros somente para HTTPS foram modificados ou excluídos.
    • Uma ou mais respostas para chamadas XHR/fetch emitidas pela página incluíam o cabeçalho HTTP Cache-control: no-store.

Experiência do usuário consistente em todas as guias

Seus usuários podem ter aberto muitas guias do seu site antes de decidirem sair. Nesse momento, ele pode ter esquecido de outras guias ou até mesmo de outras janelas do navegador. É melhor evitar depender dos usuários para fechar todas as guias e janelas relevantes. Em vez disso, adote uma postura proativa, garantindo que o estado de login do usuário seja consistente em todas as guias.

Orientações

Para alcançar um estado de login consistente em todas as guias, considere usar uma combinação de eventos pageshow/pagehide e a API Broadcast Channel.

  • Evento pageshow: após uma pageshow persistente, verifique o status de login do usuário e limpe os dados sensíveis ou até mesmo a página inteira, se o usuário não estiver mais conectado. O evento pageshow será acionado antes de a página ser renderizada pela primeira vez após ser restaurada de uma navegação para frente/para trás, o que garante que a verificação do estado de login vai permitir que você redefina a página para um estado não sensível.

    window.addEventListener('pageshow', (event) => {
      if (event.persisted && !document.cookie.match(/my-cookie)) {
        // The user has logged out.
        // Force a reload, or otherwise clear sensitive information right away.
        body.innerHTML = '';
        location.reload();
      }
    });
    
  • API Broadcast Channel: use essa API para comunicar mudanças no estado de login em guias e janelas. Se o usuário tiver feito logout, limpe todos os dados sensíveis ou redirecione para uma página de logout em todas as guias e janelas com dados sensíveis.

    // Upon logout, broadcast new login state so that other tabs can clean up too:
    const bc = new BroadcastChannel('login-state');
    bc.postMessage('logged out');
    
    // [...]
    const bc = new BroadcastChannel('login-state');
    bc.onMessage = (msgevt) => {
      if (msgevt.data === 'logged out') {
        // Clean up, reload or navigate to the sign-out page.
        // ...
      }
    }
    

Conclusão

Ao seguir as orientações deste documento, você poderá criar uma ótima experiência de desativação da conta que impede o logout acidental e protege as informações pessoais do usuário.