参考:http://harttle.com/2017/04/04/using-http-cache.html
参考:http://harttle.com/2015/08/10/cookie-session.html
本文绝大部分内容来自上述地址,做为学习资料修改后保存,感谢作者
Cookie、SessionStorage、LocalStorage 是可以被用来在浏览器端存储数据,都是字符串类型的键值对。Cookie 是为了保持HTTP的状态,后两者属于WebStorage,是用来储存客户端数据。
Cookie是存储在客户端的小型文本文件,包含若干键值对,键值对可以设置过期时间(默认过期为关闭浏览器时);
Cookie会在每次发送HTTP请求时附加到Cookie头字段,服务器根据Cookie得知用户的状态。
HTTP标准中,规定Cookie至少要有4K,至少支持300项Cookie,每个域名至少支持20项。
LocalStorage、SessionStorage 是在本地储存,不会被发送到服务器上,一般支持5-10M。
LocalStorage没有过期时间,除非手动删除它会一直存在。
SessionStorage在浏览器会话结束时(关闭标签页,不包括刷新和跳转)清空。
简单的整理
1. cookie由服务端生成,用于标识用户身份;而两个storage用于浏览器端缓存数据
2. 三者都是键值对的集合
3. 一般情况下浏览器端不会修改cookie,但会频繁操作两个storage
4. 如果保存了cookie的话,http请求中一定会带上;而两个storage可以由脚本选择性的提交
5. 会话的storage会在会话结束后销毁;而local的那个会永久保存直到覆盖。cookie会在过期时间之后销毁。
6. 安全性方面,cookie中最好不要放置任何明文的东西。两个storage的数据提交后在服务端一定要校验(其实任何payload和qs里的参数都要校验)。
Web Storage带来的好处:
1.减少网络流量:一旦数据保存在本地后,就可以避免再向服务器请求数据,因此减少不必要的数据请求,减.少数据在浏览器和服务器间不必要地来回传递。
2.快速显示数据:性能好,从本地读数据比通过网络从服务器获得数据快得多,本地数据可以即时获得。再加上网页本身也可以有缓存,因此整个页面和数据都在本地的话,可以立即显示。
3.临时存储:很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用sessionStorage非常方便
Cache-Control
Cache-control: no-cache, no-store, must-revalidate 不缓存
Cache-control: private 仅UA可缓存,代理服务器不能缓存
Cache-control: public 都可可以缓存
Cache-Control:public, max-age=31536000 指定缓存时间
image.png
Cookie 防篡改机制
1. 在服务器中配置一个不为人知的字符串(我们叫它Secret),比如:x$sfz32。
2. 当服务器需要设置Cookie时(比如authed=false),不仅设置authed的值为false, 在值的后面进一步设置一个签名,最终设置的Cookie是authed=false|6hTiBl7lVpd1P。
3. 签名6hTiBl7lVpd1P是这样生成的:Hash('x$sfz32'+'true')。 要设置的值与Secret相加再取哈希。
4. 用户收到HTTP响应并发现头字段Set-Cookie: authed=false|6hTiBl7lVpd1P。
5. 用户在发送HTTP请求时,篡改了authed值,设置头字段Cookie: authed=true|???。 因为用户不知道Secret,无法生成签名,只能随便填一个。
6.服务器收到HTTP请求,发现Cookie: authed=true|???。服务器开始进行校验: Hash('true'+'x$sfz32'),便会发现用户提供的签名不正确
Session:
Session 是存储在服务器端的,避免了在客户端Cookie中存储敏感数据。 Session 可以存储在HTTP服务器的内存中,也可以存在内存数据库(如redis)中, 对于重量级的应用甚至可以存储在数据库中。
我们以存储在redis中的Session为例,还是考察如何验证用户登录状态的问题。
1. 用户提交包含用户名和密码的表单,发送HTTP请求。
2. 服务器验证用户发来的用户名密码。
3. 如果正确则把当前用户名(通常是用户对象)存储到redis中,并生成它在redis中的ID。这个ID称为Session ID,通过Session ID可以从Redis中取出对应的用户对象, 敏感数据(比如authed=true)都存储在这个用户对象中。
4. 设置Cookie为sessionId=xxxxxx|checksum并发送HTTP响应, 仍然为每一项Cookie都设置签名。
5. 用户收到HTTP响应后,便看不到任何敏感数据了。在此后的请求中发送该Cookie给服务器。
6. 服务器收到此后的HTTP请求后,发现Cookie中有SessionID,进行放篡改验证。
7. 如果通过了验证,根据该ID从Redis中取出对应的用户对象, 查看该对象的状态并继续执行业务逻辑。
网友评论