參考:http://harttle.com/2017/04/04/using-http-cache.html
參考:http://harttle.com/2015/08/10/cookie-session.html
本文絕大部分內(nèi)容來自上述地址琉雳,做為學(xué)習(xí)資料修改后保存,感謝作者
Cookie檐束、SessionStorage被丧、LocalStorage 是可以被用來在瀏覽器端存儲數(shù)據(jù)甥桂,都是字符串類型的鍵值對邮旷。Cookie 是為了保持HTTP的狀態(tài)婶肩,后兩者屬于WebStorage律歼,是用來儲存客戶端數(shù)據(jù)。
Cookie是存儲在客戶端的小型文本文件制圈,包含若干鍵值對鲸鹦,鍵值對可以設(shè)置過期時間(默認過期為關(guān)閉瀏覽器時)馋嗜;
Cookie會在每次發(fā)送HTTP請求時附加到Cookie頭字段域庇,服務(wù)器根據(jù)Cookie得知用戶的狀態(tài)听皿。
HTTP標準中宽档,規(guī)定Cookie至少要有4K吗冤,至少支持300項Cookie,每個域名至少支持20項覆致。
LocalStorage、SessionStorage 是在本地儲存儡羔,不會被發(fā)送到服務(wù)器上,一般支持5-10M。
LocalStorage沒有過期時間璧诵,除非手動刪除它會一直存在汰蜘。
SessionStorage在瀏覽器會話結(jié)束時(關(guān)閉標簽頁,不包括刷新和跳轉(zhuǎn))清空之宿。
簡單的整理
1. cookie由服務(wù)端生成,用于標識用戶身份;而兩個storage用于瀏覽器端緩存數(shù)據(jù)
2. 三者都是鍵值對的集合
3. 一般情況下瀏覽器端不會修改cookie,但會頻繁操作兩個storage
4. 如果保存了cookie的話,http請求中一定會帶上;而兩個storage可以由腳本選擇性的提交
5. 會話的storage會在會話結(jié)束后銷毀;而local的那個會永久保存直到覆蓋族操。cookie會在過期時間之后銷毀。
6. 安全性方面,cookie中最好不要放置任何明文的東西比被。兩個storage的數(shù)據(jù)提交后在服務(wù)端一定要校驗(其實任何payload和qs里的參數(shù)都要校驗)色难。
Web Storage帶來的好處:
1.減少網(wǎng)絡(luò)流量:一旦數(shù)據(jù)保存在本地后,就可以避免再向服務(wù)器請求數(shù)據(jù)姐赡,因此減少不必要的數(shù)據(jù)請求莱预,減.少數(shù)據(jù)在瀏覽器和服務(wù)器間不必要地來回傳遞。
2.快速顯示數(shù)據(jù):性能好项滑,從本地讀數(shù)據(jù)比通過網(wǎng)絡(luò)從服務(wù)器獲得數(shù)據(jù)快得多依沮,本地數(shù)據(jù)可以即時獲得枪狂。再加上網(wǎng)頁本身也可以有緩存,因此整個頁面和數(shù)據(jù)都在本地的話薄嫡,可以立即顯示。
3.臨時存儲:很多時候數(shù)據(jù)只需要在用戶瀏覽一組頁面期間使用,關(guān)閉窗口后數(shù)據(jù)就可以丟棄了,這種情況使用sessionStorage非常方便
Cache-Control
Cache-control: no-cache, no-store, must-revalidate 不緩存
Cache-control: private 僅UA可緩存,代理服務(wù)器不能緩存
Cache-control: public 都可可以緩存
Cache-Control:public, max-age=31536000 指定緩存時間
Cookie 防篡改機制
1. 在服務(wù)器中配置一個不為人知的字符串(我們叫它Secret)险胰,比如:x$sfz32榆综。
2. 當服務(wù)器需要設(shè)置Cookie時(比如authed=false),不僅設(shè)置authed的值為false, 在值的后面進一步設(shè)置一個簽名挪哄,最終設(shè)置的Cookie是authed=false|6hTiBl7lVpd1P斯入。
3. 簽名6hTiBl7lVpd1P是這樣生成的:Hash('x$sfz32'+'true')涵防。 要設(shè)置的值與Secret相加再取哈希。
4. 用戶收到HTTP響應(yīng)并發(fā)現(xiàn)頭字段Set-Cookie: authed=false|6hTiBl7lVpd1P。
5. 用戶在發(fā)送HTTP請求時证舟,篡改了authed值,設(shè)置頭字段Cookie: authed=true|???。 因為用戶不知道Secret,無法生成簽名,只能隨便填一個。
6.服務(wù)器收到HTTP請求,發(fā)現(xiàn)Cookie: authed=true|???。服務(wù)器開始進行校驗: Hash('true'+'x$sfz32'),便會發(fā)現(xiàn)用戶提供的簽名不正確
Session:
Session 是存儲在服務(wù)器端的,避免了在客戶端Cookie中存儲敏感數(shù)據(jù)。 Session 可以存儲在HTTP服務(wù)器的內(nèi)存中,也可以存在內(nèi)存數(shù)據(jù)庫(如redis)中, 對于重量級的應(yīng)用甚至可以存儲在數(shù)據(jù)庫中。
我們以存儲在redis中的Session為例,還是考察如何驗證用戶登錄狀態(tài)的問題。
1. 用戶提交包含用戶名和密碼的表單晾捏,發(fā)送HTTP請求惦辛。
2. 服務(wù)器驗證用戶發(fā)來的用戶名密碼胖齐。
3. 如果正確則把當前用戶名(通常是用戶對象)存儲到redis中,并生成它在redis中的ID呀伙。這個ID稱為Session ID,通過Session ID可以從Redis中取出對應(yīng)的用戶對象阳准, 敏感數(shù)據(jù)(比如authed=true)都存儲在這個用戶對象中。
4. 設(shè)置Cookie為sessionId=xxxxxx|checksum并發(fā)送HTTP響應(yīng)帮寻, 仍然為每一項Cookie都設(shè)置簽名。
5. 用戶收到HTTP響應(yīng)后,便看不到任何敏感數(shù)據(jù)了舅列。在此后的請求中發(fā)送該Cookie給服務(wù)器。
6. 服務(wù)器收到此后的HTTP請求后卧蜓,發(fā)現(xiàn)Cookie中有SessionID帐要,進行放篡改驗證。
7. 如果通過了驗證弥奸,根據(jù)該ID從Redis中取出對應(yīng)的用戶對象榨惠, 查看該對象的狀態(tài)并繼續(xù)執(zhí)行業(yè)務(wù)邏輯。