一文理解 cookie、localStorage、sessionStorage、session

簡介

在之前常常用到的cookiesession,但在H5中新引入了新的瀏覽器本地緩存方案。由於你們使用的不太規範用來做爲本地儲存工具,在下次請求時會默認帶上cookie中的數據致使浪費性能和流量。javascript

下面就從開始介紹爲何產生的cookie,它的出現是爲了解決什麼問題,它有什麼問題;後面localStorage是爲何產生,它又解決了那部分的問題。最後是cookiesessionlocalStoragesessionStorage之間的對比。php

cookie

首先了解爲何會產生cookie?cookie是什麼?html

cookie是什麼、cookie產生緣由

HTTP請求創建鏈接時,有一個客戶端服務端它們兩個之間創建的鏈接。可是HTTP協議每次創建鏈接都是獨立,也能夠說是HTTP協議是無狀態的鏈接。java

  • 第一次創建鏈接,客戶在客戶端中登陸,服務端驗證登陸信息,生成Token爲之後的請求不須要重新登陸
  • 第二次創建鏈接,客戶端攜帶服務端在登陸成功時返回的Token,可是這個Token要儲存在哪裏?通常會存在cookie裏。

簡單總結一下就是,由於HTTP協議是無狀態的因此客戶端須要一個cookie來儲存起來。web

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的真正區別

相關文章
相關標籤/搜索