Cookies and local storage serve different purposes. Cookies are primarily for reading server-side, local storage can only be read by the client-side. So the question is, in your app, who needs this data — the client or the server?
If it's your client (your JavaScript), then by all means switch. You're wasting bandwidth by sending all the data in each HTTP header.
If it's your server, local storage isn't so useful because you'd have to forward the data along somehow (with Ajax or hidden form fields or something). This might be okay if the server only needs a small subset of the total data for each request.
You'll want to leave your session cookie as a cookie either way though.
As per the technical difference, and also my understanding:
Apart from being an old way of saving data, Cookies give you a limit of 4096 bytes (4095, actually) — it's per cookie. Local Storage is as big as 10MB per domain — this Stack Overflow question also mentions it.
localStorage is an implementation of the Storage Interface. It stores data with no expiration date, and gets cleared only through JavaScript, or clearing the Browser Cache / Locally Stored Data — unlike cookie expiry.
In the context of JWTs, Stormpath have written a fairly helpful article outlining possible ways to store them, and the (dis-)advantages pertaining to each method.
It also has a short overview of XSS and CSRF attacks, and how you can combat them.
I've attached some short snippets of the article below, in case their article is taken offline/their site goes down.
Local Storage
Problems:
Web Storage (localStorage/sessionStorage) is accessible through JavaScript on the same domain. This means that any JavaScript running on your site will have access to web storage, and because of this can be vulnerable to cross-site scripting (XSS) attacks. XSS in a nutshell is a type of vulnerability where an attacker can inject JavaScript that will run on your page. Basic XSS attacks attempt to inject JavaScript through form inputs, where the attacker puts alert('You are Hacked'); into a form to see if it is run by the browser and can be viewed by other users.
Prevention:
To prevent XSS, the common response is to escape and encode all untrusted data. But this is far from the full story. In 2015, modern web apps use JavaScript hosted on CDNs or outside infrastructure. Modern web apps include 3rd party JavaScript libraries for A/B testing, funnel/market analysis, and ads. We use package managers like Bower to import other peoples’ code into our apps.
What if only one of the scripts you use is compromised? Malicious JavaScript can be embedded on the page, and Web Storage is compromised. These types of XSS attacks can get everyone’s Web Storage that visits your site, without their knowledge. This is probably why a bunch of organizations advise not to store anything of value or trust any information in web storage. This includes session identifiers and tokens.
As a storage mechanism, Web Storage does not enforce any secure standards during transfer. Whoever reads Web Storage and uses it must do their due diligence to ensure they always send the JWT over HTTPS and never HTTP.
Cookies
Problems:
Cookies, when used with the HttpOnly cookie flag, are not accessible through JavaScript, and are immune to XSS. You can also set the Secure cookie flag to guarantee the cookie is only sent over HTTPS. This is one of the main reasons that cookies have been leveraged in the past to store tokens or session data. Modern developers are hesitant to use cookies because they traditionally required state to be stored on the server, thus breaking RESTful best practices. Cookies as a storage mechanism do not require state to be stored on the server if you are storing a JWT in the cookie. This is because the JWT encapsulates everything the server needs to serve the request.
However, cookies are vulnerable to a different type of attack: cross-site request forgery (CSRF). A CSRF attack is a type of attack that occurs when a malicious web site, email, or blog causes a user’s web browser to perform an unwanted action on a trusted site on which the user is currently authenticated. This is an exploit of how the browser handles cookies. A cookie can only be sent to the domains in which it is allowed. By default, this is the domain that originally set the cookie. The cookie will be sent for a request regardless of whether you are on galaxies.com or hahagonnahackyou.com.
Prevention:
Modern browsers support the SameSite flag, in addition to HttpOnly and Secure. The purpose of this flag is to prevent the cookie from being transmitted in cross-site requests, preventing many kinds of CSRF attack.
For browsers that do not support SameSite, CSRF can be prevented by using synchronized token patterns. This sounds complicated, but all modern web frameworks have support for this.
For example, AngularJS has a solution to validate that the cookie is accessible by only your domain. Straight from AngularJS docs:
When performing XHR requests, the $http service reads a token from a cookie (by default, XSRF-TOKEN) and sets it as an HTTP header (X-XSRF-TOKEN). Since only JavaScript that runs on your domain can read the cookie, your server can be assured that the XHR came from JavaScript running on your domain. You can make this CSRF protection stateless by including a xsrfToken JWT claim:
Leveraging your web app framework’s CSRF protection makes cookies rock solid for storing a JWT. CSRF can also be partially prevented by checking the HTTP Referer and Origin header from your API. CSRF attacks will have Referer and Origin headers that are unrelated to your application.
/*
* 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
}
With localStorage, web applications can store data locally within the user's browser. Before HTML5, application data had to be stored in cookies, included in every server request. Large amounts of data can be stored locally, without affecting website performance. Although localStorage is more modern, there are some pros and cons to both techniques.
Cookies
Pros
Legacy support (it's been around forever)
Persistent data
Expiration dates
Cookies can be marked as HTTPOnly which might limit XSS atacks to user browser during his sesion (does not guarantee full immunity to XSS atacks).
Cons
Each domain stores all its cookies in a single string, which can make parsing data difficult
Data is unencrypted, which becomes an issue because... ... though small in size, cookies are sent with every HTTP request Limited size (4KB)
Local storage
Pros
Support by most modern browsers
Persistent data that is stored directly in the browser
Same-origin rules apply to local storage data
Is not sent with every HTTP request
~5MB storage per domain (that's 5120KB)
Cons
Not supported by anything before: IE 8, Firefox 3.5, Safari 4, Chrome 4, Opera 10.5, iOS 2.0, Android 2.0
If the server needs stored client information you purposely have to send it.
localStorage usage is almost identical with the session one. They have pretty much exact methods, so switching from session to localStorage is really child's play. However, if stored data is really crucial for your application, you will probably use cookies as a backup in case localStorage is not available. If you want to check browser support for localStorage, all you have to do is run this simple 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
}
"localStorage values on Secure (SSL) pages are isolated" as someone noticed keep in mind that localStorage will not be available if you switch from 'http' to 'https' secured protocol, where the cookie will still be accesible. This is kind of important to be aware of if you work with secure protocols.
Note: Starting with iOS 5.1, Safari Mobile stores localStorage data in the cache folder, which is subject to occasional clean up, at the behest of the OS, typically if space is short. Safari Mobile's Private Browsing mode also prevents writing to localStorage entirely.
is accessible by JavaScript so Cookie's data can be stolen by XSS attack(Cross Site Scripting attack) but setting HttpOnly flag to Cookie prevents the access by JavaScript so Cookie's data is protected from XSS attack.
is vulnerable to CSRF(Cross Site Request Forgery) but setting SameSite flag with Lax to Cookie mitigates CSRF and setting SameSite flag with Strict to Cookie prevents CSRF.
must have expiry date so when expiry date passes, Cookie is deleted automatically so even if you forgot to delete Cookie, Cookie is deleted automatically because of expiry date.
is about 4KB as a common size (depending on browsers).
Local Storage:
is accessible by JavaScript so Local Storage's data can be stolen by XSS attack(Cross Site Scripting attack) then, as logn as I researched, there are no easy preventions for Local Storage from XSS attack.
is not vulnerable to CSRF(Cross Site Request Forgery).
doesn't have expiry date so if you forgot to delete Local Storage data, Local Storage data can stay forever.
is about 5MB as a common size (depending on browsers).
I recommend using Cookie for sensitive data and Local Storage for non-sensitive data.
Well, local storage speed greatly depends on the browser the client is using, as well as the operating system. Chrome or Safari on a mac could be much faster than Firefox on a PC, especially with newer APIs. As always though, testing is your friend (I could not find any benchmarks).
I really don't see a huge difference in cookie vs local storage. Also, you should be more worried about compatibility issues: not all browsers have even begun to support the new HTML5 APIs, so cookies would be your best bet for speed and compatibility.
发布评论
评论(9)
Cookie 和本地存储有不同的用途。 Cookie主要用于服务器端读取,本地存储只能由客户端读取。所以问题是,在您的应用程序中,谁需要这些数据——客户端还是服务器?
如果它是你的客户端(你的 JavaScript),那么一定要切换。发送每个 HTTP 标头中的所有数据会浪费带宽。
如果是您的服务器,则本地存储就没那么有用,因为您必须以某种方式转发数据(使用 Ajax 或隐藏表单字段或其他方式)。如果服务器只需要每个请求的总数据的一小部分,这可能没问题。
无论哪种方式,您都希望将会话 cookie 作为 cookie 保留。
根据技术差异以及我的理解:
除了是旧方式之外在保存数据时,Cookie 给您的限制是 4096 字节(实际上是 4095)——这是针对每个 cookie 的。本地存储大小为每个域 10MB - 此堆栈溢出问题也提到了。
localStorage
是Storage
接口的实现。它存储的数据没有过期日期,并且仅通过 JavaScript 清除,或清除浏览器缓存/本地存储的数据 - 与 cookie 过期不同。Cookies and local storage serve different purposes. Cookies are primarily for reading server-side, local storage can only be read by the client-side. So the question is, in your app, who needs this data — the client or the server?
If it's your client (your JavaScript), then by all means switch. You're wasting bandwidth by sending all the data in each HTTP header.
If it's your server, local storage isn't so useful because you'd have to forward the data along somehow (with Ajax or hidden form fields or something). This might be okay if the server only needs a small subset of the total data for each request.
You'll want to leave your session cookie as a cookie either way though.
As per the technical difference, and also my understanding:
Apart from being an old way of saving data, Cookies give you a limit of 4096 bytes (4095, actually) — it's per cookie. Local Storage is as big as 10MB per domain — this Stack Overflow question also mentions it.
localStorage
is an implementation of theStorage
Interface. It stores data with no expiration date, and gets cleared only through JavaScript, or clearing the Browser Cache / Locally Stored Data — unlike cookie expiry.在 JWT 的背景下,Stormpath 写了一篇相当有用的文章,概述了存储它们的可能方法,以及与每种方法相关的(缺点)优点。
它还简要概述了 XSS 和 CSRF 攻击以及如何应对它们。
我附上了下面文章的一些简短片段,以防他们的文章离线/网站瘫痪。
本地存储
问题:
预防:
Cookie
问题:
预防:
完整的文章可以在这里找到:
https://stormpath.com/ blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/
他们还有一篇有用的文章,介绍如何最好地设计和实现 JWT,以及令牌本身的结构:
https://stormpath.com/blog/jwt-the-right-way/
In the context of JWTs, Stormpath have written a fairly helpful article outlining possible ways to store them, and the (dis-)advantages pertaining to each method.
It also has a short overview of XSS and CSRF attacks, and how you can combat them.
I've attached some short snippets of the article below, in case their article is taken offline/their site goes down.
Local Storage
Problems:
Prevention:
Cookies
Problems:
Prevention:
The full article can be found here:
https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/
They also have a helpful article on how to best design and implement JWTs, with regards to the structure of the token itself:
https://stormpath.com/blog/jwt-the-right-way/
通过
localStorage
,Web 应用程序可以在用户浏览器中本地存储数据。在 HTML5 之前,应用程序数据必须存储在 cookie 中,并包含在每个服务器请求中。可以在本地存储大量数据,而不影响网站性能。尽管localStorage
更现代,但这两种技术都有一些优点和缺点。Cookie 的
优点
每个
解析数据很困难
尺寸小,cookie 随每个 HTTP 请求一起发送 大小有限
(4KB)
本地存储
优点
缺点
发送它。
localStorage
的用法与会话几乎相同。它们有非常精确的方法,因此从会话切换到 localStorage 确实是小菜一碟。但是,如果存储的数据对于您的应用程序确实至关重要,您可能会使用 cookie 作为备份,以防localStorage
不可用。如果您想检查浏览器对localStorage
的支持,您所要做的就是运行这个简单的脚本:With
localStorage
, web applications can store data locally within the user's browser. Before HTML5, application data had to be stored in cookies, included in every server request. Large amounts of data can be stored locally, without affecting website performance. AlthoughlocalStorage
is more modern, there are some pros and cons to both techniques.Cookies
Pros
Cons
parsing data difficult
small in size, cookies are sent with every HTTP request Limited size
(4KB)
Local storage
Pros
Cons
to send it.
localStorage
usage is almost identical with the session one. They have pretty much exact methods, so switching from session tolocalStorage
is really child's play. However, if stored data is really crucial for your application, you will probably use cookies as a backup in caselocalStorage
is not available. If you want to check browser support forlocalStorage
, all you have to do is run this simple script:Cookie:
本地存储:
Cookies:
Local Storage:
主要区别:
容量:
浏览器支持:
存储位置:
随请求发送:
访问来源:
到期日期:
注意:用那个,适合你的。
Key Differences:
Capacity:
Browser Support:
Storage Location:
Send With Request:
Accessed From:
Expiry Date:
Note: Use that, what suits you.
另外值得一提的是,当用户在某些版本的移动 Safari 中以“私密”模式浏览时,无法使用
localStorage
。引用自 WayBack Archive of 2018 年关于
Window.localStorage
的 MDN 主题:It is also worth mentioning that
localStorage
cannot be used when users browse in "private" mode in some versions of mobile Safari.Quoted from WayBack Archive of MDN topic on
Window.localStorage
back in 2018:Cookie:
可以通过JavaScript访问,因此Cookie的数据可以通过XSS窃取
攻击(跨站脚本攻击),但设置 HttpOnly 标志
Cookie 阻止 JavaScript 的访问,因此 Cookie 的数据
免受XSS 攻击。
容易受到CSRF(跨站请求伪造)的攻击,但设置
将 SameSite 标志 Lax 设置为 Cookie 可缓解 CSRF 并将 SameSite 标志设置 Strict 设置为 Cookie 防止
CSRF。
必须有到期日期,因此当到期日期过去时,Cookie
自动删除,因此即使您忘记删除 Cookie,
Cookie 由于过期而被自动删除。
一般大小约为4KB(取决于浏览器)。
本地存储:
可通过JavaScript访问,因此本地存储的数据可能被XSS窃取
攻击(跨站脚本攻击) 然后,正如我研究的那样,
没有简单的方法可以预防本地存储遭受XSS攻击
攻击。
不容易受到CSRF(跨站请求伪造)的攻击。</p>
没有过期日期,因此如果您忘记删除本地存储
数据,本地存储数据可以永久保留。
一般大小约为5MB(取决于浏览器)。
我建议对敏感数据使用Cookie,对非敏感数据使用本地存储。
Cookie:
is accessible by JavaScript so Cookie's data can be stolen by XSS
attack(Cross Site Scripting attack) but setting HttpOnly flag
to Cookie prevents the access by JavaScript so Cookie's data is
protected from XSS attack.
is vulnerable to CSRF(Cross Site Request Forgery) but setting
SameSite flag with Lax to Cookie mitigates CSRF and setting SameSite flag with Strict to Cookie prevents
CSRF.
must have expiry date so when expiry date passes, Cookie is
deleted automatically so even if you forgot to delete Cookie,
Cookie is deleted automatically because of expiry date.
is about 4KB as a common size (depending on browsers).
Local Storage:
is accessible by JavaScript so Local Storage's data can be stolen by XSS
attack(Cross Site Scripting attack) then, as logn as I researched,
there are no easy preventions for Local Storage from XSS
attack.
is not vulnerable to CSRF(Cross Site Request Forgery).
doesn't have expiry date so if you forgot to delete Local Storage
data, Local Storage data can stay forever.
is about 5MB as a common size (depending on browsers).
I recommend using Cookie for sensitive data and Local Storage for non-sensitive data.
本地存储最多可存储 5MB 离线数据,而会话也最多可存储 5MB 数据。但cookie只能存储4kb的文本格式数据。
LOCAL和Session以JSON格式存储数据,因此易于解析。但cookies数据是字符串格式的。
图片参考:https:// tutorial.techaltum.com/local-and-session-storage.html
Local storage can store up to 5mb offline data, whereas session can also store up to 5 mb data. But cookies can store only 4kb data in text format.
LOCAl and Session storage data in JSON format, thus easy to parse. But cookies data is in string format.
Image reference: https://tutorial.techaltum.com/local-and-session-storage.html
那么,本地存储速度很大程度上取决于客户端使用的浏览器以及操作系统。 Mac 上的 Chrome 或 Safari 可能比 PC 上的 Firefox 快得多,尤其是使用更新的 API 时。一如既往,测试是你的朋友(我找不到任何基准)。
我真的没有看到 cookie 与本地存储之间有很大的区别。此外,您应该更担心兼容性问题:并非所有浏览器都开始支持新的 HTML5 API,因此 cookie 将是速度和兼容性的最佳选择。
Well, local storage speed greatly depends on the browser the client is using, as well as the operating system. Chrome or Safari on a mac could be much faster than Firefox on a PC, especially with newer APIs. As always though, testing is your friend (I could not find any benchmarks).
I really don't see a huge difference in cookie vs local storage. Also, you should be more worried about compatibility issues: not all browsers have even begun to support the new HTML5 APIs, so cookies would be your best bet for speed and compatibility.