一文理解 cookie、localStorage、sessionStorage、session

5,927 阅读12分钟

简介

在以前经常用到的cookiesession,但在H5中新引入了新的浏览器本地缓存方案。因为大家使用的不太规范用来作为本地储存工具,在下次请求时会默认带上cookie中的数据导致浪费性能和流量。

下面就从开始介绍为什么产生的cookie,它的出现是为了解决什么问题,它有什么问题;后面localStorage是为什么产生,它又解决了那部分的问题。最后是cookiesessionlocalStoragesessionStorage之间的对比。

cookie

首先了解为什么会产生cookie?cookie是什么?

cookie是什么、cookie产生原因

HTTP请求建立连接时,有一个客户端服务端它们两个之间建立的连接。但是HTTP协议每次建立连接都是独立,也可以说是HTTP协议是无状态的连接。

  • 第一次建立连接,客户在客户端中登录,服务端验证登录信息,生成Token为以后的请求不需要从新登录
  • 第二次建立连接,客户端携带服务端在登录成功时返回的Token,但是这个Token要储存在哪里?一般会存在cookie里。

简单总结一下就是,因为HTTP协议是无状态的所以客户端需要一个cookie来储存起来。

HTTP Cookie(也叫Web Cookie或浏览器Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。

Cookie主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

创建Cookie

当服务器收到HTTP请求时,服务器可以在响应头里面添加一个Set-Cookie选项。浏览器收到响应后通常会保存下Cookie,之后对该服务器每一次请求中都通过Cookie请求头部将Cookie信息发送给服务器。

在创建Cookie是可以设置很多属性,如ExpiresMax-AgeDomainPathSecureHttpOnly,因为它会自动携带到服务器端,同时又支持服务器端设置。所以有很多的方面要注意,比如时效性作用域安全性。下面就从这三个方面来解释他属性的作用。

时效性

如果在Set-Cookie时不通过ExpriesMax-Age两个字段设置Cookie的时效性,那么这个Cookie是一个简单的会话期Cookie。它在关闭浏览器是会被自动删除。

如果设置了ExpriesMax-Age那么这个Cookie在指定时间内都是有效的。

提示:当Cookie的过期时间被设定时,设定的日期和时间只与客户端相关,而不是服务端。

作用域

DomainPath 标识定义了Cookie的作用域:即Cookie应该发送给哪些URL

Domain 标识指定了哪些主机可以接受Cookie。如果不指定,默认为当前文档的主机(不包含子域名)。如果指定了Domain,则一般包含子域名。

Path 标识指定了主机下的哪些路径可以接受Cookie(该URL路径必须存在于请求URL中)。以字符 %x2F ("/") 作为路径分隔符,子路径也会被匹配。

安全性

标记为 SecureCookie只应通过被HTTPS协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过Cookie传输,因为Cookie有其固有的不安全性,Secure 标记也无法提供确实的安全保障。

从 Chrome 52 和 Firefox 52 开始,不安全的站点(http:)无法使用Cookie的 Secure 标记。

为避免跨域脚本 (XSS) 攻击,通过JavaScriptDocument.cookie API无法访问带有 HttpOnly 标记的Cookie,它们只应该发送给服务端。

客户端操作Cookie

通过Document.cookie属性可创建新的Cookie,也可通过该属性访问非HttpOnly标记的Cookie

  documnet.cookie
  // 这里就不多做赘述,有一篇文章专门讲解了

cookie的特点

优点

  • 储存用户信息(用户token)
  • 标记用户行为(uuid、埋点)

弊端

  • Cookie会被附加在每个HTTP请求中,所以无形中增加了流量

  • Cookie可能被禁用。当用户非常注重个人隐私保护时,他很可能禁用浏览器的Cookie功能;

  • 由于在HTTP请求中的Cookie是明文传递的,潜在的安全风险,Cookie 可能会被篡改

  • Cookie数量和长度的限制。每个域名(Domain)下 IE6或IE6-(IE6以下版本):最多20个cookie IE7或IE7+(IE7以上版本):最多50个cookie FF:最多50个cookie Opera:最多30个cookie Chrome和safari没有硬性限制 当超过单个域名限制之后,再设置cookie,浏览器就会清除以前设置的cookie。IE和Opera会清理近期最少使用的cookie,FF会随机清理cookie;

  • 每个Cookie长度不能超过4KB

cookie安全问题

Cookie面临什么样的安全问题,常见的xsscsrf等等下面开始。

xss 和 防御xss

如果在服务器端Set-Cookie时没有设置HttpOnly=true时,在浏览器端就可以通过document.cookie来读取和修改Cookie中的值,这是十分安全的会造成xss。当Cookie中有关键性信息是要设置HttpOnly=true

防止中间人劫持 和 中间人劫持

大致的分布图是:

         DNS
     <----->
用户          中间人       外网
     <----->
       HTTP

当使用HTTPS协议和购买正规的CA证书时,即使中间人劫持也无法解密。并且在Set-Cookie设置Secure=trueCookie只应通过被HTTPS协议加密过的请求发送给服务端。

csrf 和 csrf防御

CSRF: 跨站请求伪造(CSRF)是一种冒充受信任用户,向服务器发送非预期请求的攻击方式。

例如,这些非预期请求可能是通过在跳转链接后的 URL 中加入恶意参数来完成:

<img src="https://www.example.com/index.php?action=delete&id=123">

对于在 https://www.example.com 有权限的用户,这个 <img> 标签会在他们根本注意不到的情况下对 https://www.example.com 执行这个操作,即使这个标签根本不在 https://www.example.com 内亦可。

SameSite Cookie允许服务器要求某个cookie在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)。但目前SameSite Cookie还处于实验阶段,并不是所有浏览器都支持。

  • strict:浏览器在任何跨域请求中都不会携带Cookie,这样可以有效的防御CSRF攻击,但是对于有多个子域名的网站采用主域名存储用户登录信息的场景,每个子域名都需要用户重新登录,造成用户体验非常的差。
  • lax:相比较strict,它允许从三方网站跳转过来的时候使用Cookie

其他防御

  • 设置cookie有效期时间
  • 防止cookie是明文,服务器端生成密钥验证
  • 生成随机数和cookie发送给服务器端
  • flash编程安全,审核flash代码,尽量不要用flash用最新的视频vedio + https + socket或者动画

到此cookie产生原因作用特点/缺点安全问题

Session

session是什么? Session是一种记录客户状态的机制,不同于Cookie的是Cookie保存在客户端浏览器中,而Session保存在服务器上。避免了在客户端Cookie中存储敏感数据。

Session机制

Session从字面意思上可以理解为会话,谁与谁的会话呢?其实是客户端浏览器与服务器之间一系列交互的动作称为一个 Session

创建Session(java)

  1. Session在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法, 在Java中是通过调用HttpServletRequestgetSession方法(使用true作为参数)创建的。 创建Session的同时,服务器会为该Session生成唯一的session id, 这个session id在随后的请求中会被用来重新获得已经创建的Session
  2. Session被创建之后,就可以调用Session相关的方法往Session中增加内容了, 而这些内容只会保存在服务器中,发到客户端的只有session id
  3. 当客户端再次发送请求的时候,会将这个session id带上, 服务器接受到请求之后就会依据session id找到相应的Session,从而再次使用Session

Session的生命周期

Session保存在服务器端。为了获得更高的存取速度,服务器一般把Session放在内存中。 每个用户都会有一个独立的Session。 如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。 因此,Session里的信息应该尽量精简。

Session在用户第一次访问服务器的时候自动创建。 需要注意只有访问JSP、Servlet等程序时才会创建Session, 只访问HTML、IMAGE等静态资源并不会创建Session。 如果尚未生成Session,也可以使用request.getSession(true)强制生成Session

Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。 用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session"活跃(active)"了一次

Session的有效期

由于会有越来越多的用户访问服务器,因此Session也会越来越多。 为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。 这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。

Session的超时时间为maxInactiveInterval属性, 可以通过对应的getMaxInactiveInterval()获取,通过setMaxInactiveInterval(longinterval)修改。

Session的超时时间也可以在web.xml中修改。 另外,通过调用Sessioninvalidate()方法可以使Session失效。

三种方法让Session失效:

  • 服务器意外关闭。(服务器正常关闭时session是会被服务器保存在服务器的 session.ser 文件中(在work文件夹下))
  • session自杀: 调用session.invalidate()方法可以立即杀死session
  • 可以在服务器下的web.xml文件中的 <session-timeout> 30 </session-timeout> 修改这是默认值(默认30分钟),是以分为单位。

浏览器关闭session会失效?

在几年前看很多网上的资料时有的会说session会在浏览器关闭时会失效。为什么会失效?怎么能让它不失效?

为什么会失效?

下面梳理一下session为什么会在浏览器关闭时失效,其实这样说并不准确:

  1. 在服务器端生成session,并且把sessionid通过set-cookie发送给浏览器
  2. 以后每次请求除了图片、静态文件请求,其它的请求都会带上服务端写入浏览器中cookie
  3. 服务端接收到sessionid,通过sessionid找到对应的session信息
  4. 当浏览器关闭时,当前域名中设置的cookie会被清空
  5. 再下次请求使,服务端接收到的sessionnull,服务端就会认为当前用户是一个新的用户,重新登录或者直接设置新的sessionid

上面也就是为什么会说session会在浏览器关闭时会失效。

怎么能让它不失效?

Set-Cookie时设置ExpriesMax-Age,其实就是设置Cookie的失效时间。 或者直接把Sessionid储存在本地。

web Storage

Web Storage API提供机制, 使浏览器能以一种比使用Cookie更直观的方式存储键/值对。

Web Storage 包含如下两种机制:

  • sessionStorage 为每一个给定的源(given origin)维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。
  • localStorage 同样的功能,但是在浏览器关闭,然后重新打开后数据仍然存在。

应注意,无论数据存储在 localStorage 还是 sessionStorage ,它们都特定于页面的协议。

localStorage

只读的localStorage 属性允许你访问一个Document 源(origin)的对象 Storage;存储的数据将保存在浏览器会话中。存储在 localStorage 的数据可以长期保留。

sessionStorage

sessionStorage 属性允许你访问一个 session Storage 对象。存储在 sessionStorage 里面的数据在页面会话结束时会被清除。页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。在新标签或窗口打开一个页面时会在顶级浏览上下文中初始化一个新的会话,这点和 session cookies 的运行方式不同。

localStorage和sessionStorage区别

存储在 localStorage 的数据可以长期保留,而存储在 sessionStorage 里面的数据在页面会话结束时会被清除。

总结

sessioncookie的区别:

  • session储存在服务端,cookie储存在客户端
  • sessioncookie更安全,因为session储存在服务端
  • session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中。
  • cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现session的一种方式。

web storagecookie的区别:

  • web storagescookie的作用不同,web storage是用于本地大容量存储数据(web storage的存储量大到5MB);而cookie是用于客户端和服务端间的信息传递;
  • web storagesetItemgetItemremoveItemclear等方法,cookie需要我们自己来封装setCookiegetCookieremoveCookie

参考

HTTP cookies

Web Storage API

Window.localStorage

Window.sessionStorage

这一次把cookie给你说透彻!

深入理解Session和Cookie的区别

详解cookie和session的运作机制(上篇)

面试稳了!这才是cookie,session与token的真正区别