cookie,session壤圃,localStorage和sessionStorage

前言

http是一個無狀態(tài)協(xié)議陵霉。什么是無狀態(tài)呢?就是說這一次請求和上一次請求是沒有任何關(guān)系的伍绳,互不認(rèn)識的踊挠,沒有關(guān)聯(lián)的。這種無狀態(tài)的的好處是快速冲杀。壞處是假如我們想要把www.zhihu.com/login.htmlwww.zhihu.com/index.html關(guān)聯(lián)起來止毕,必須使用某些手段和工具。

Cookie

Cookie是小甜餅的意思漠趁,主要有以下特點:

  • 顧名思義扁凛,Cookie 確實非常小,它的大小限制為4KB左右
  • 主要用途是保存登錄信息和標(biāo)記用戶(比如購物車)等闯传,不過隨著localStorage的出現(xiàn)谨朝,現(xiàn)在購物車的工作Cookie承擔(dān)的較少了
  • 一般由服務(wù)器生成,可設(shè)置失效時間甥绿。如果在瀏覽器端生成Cookie字币,默認(rèn)是關(guān)閉瀏覽器后失效
  • 每次都會攜帶在HTTP頭中,如果使用cookie保存過多數(shù)據(jù)會帶來性能問題
  • 原生API不如storage友好共缕,需要自己封裝函數(shù)
API用法

服務(wù)端向客戶端發(fā)送的cookie(HTTP頭,不帶參數(shù)):
Set-Cookie: <cookie-name>=<cookie-value> (name可選)

服務(wù)端向客戶端發(fā)送的cookie(HTTP頭洗出,帶參數(shù)):
Set-Cookie: <cookie-name>=<cookie-value>;(可選參數(shù)1);(可選參數(shù)2)

客戶端設(shè)置cookie:

document.cookie = "<cookie-name>=<cookie-value>;(可選參數(shù)1);(可選參數(shù)2)"

可選參數(shù):
Expires=<date>:cookie的最長有效時間,若不設(shè)置則cookie生命期與會話期相同

Max-Age=<non-zero-digit>:cookie生成后失效的秒數(shù)

Domain=<domain-value>:指定cookie可以送達(dá)的主機域名图谷,若一級域名設(shè)置了則二級域名也能獲取翩活。

Path=<path-value>:指定一個URL阱洪,例如指定path=/docs,則”/docs”菠镇、”/docs/Web/“冗荸、”/docs/Web/Http”均滿足匹配條件

Secure:必須在請求使用SSL或HTTPS協(xié)議的時候cookie才回被發(fā)送到服務(wù)器

HttpOnly:客戶端無法更改Cookie,客戶端設(shè)置cookie時不能使用這個參數(shù)利耍,一般是服務(wù)器端使用

示例:

Set-Cookie: sessionid=aes7a8; HttpOnly; Path=/

document.cookie = "KMKNKK=1234;Sercure"

可選前綴:
__Secure-:以__Secure-為前綴的cookie蚌本,必須與secure屬性一同設(shè)置,同時必須應(yīng)用于安全頁面(即使用HTTPS)

__Host-:以__Host-為前綴的cookie隘梨,必須與secure屬性一同設(shè)置程癌,同時必須應(yīng)用于安全頁面(即使用HTTPS)。必須不能設(shè)置domian屬性(這樣可以防止二級域名獲取一級域名的cookie)轴猎,path屬性的值必須為”/“嵌莉。

前綴使用示例:

Set-Cookie: __Secure-ID=123; Secure; Domain=example.com
Set-Cookie: __Host-ID=123; Secure; Path=/

document.cookie = "__Secure-KMKNKK=1234;Sercure"
document.cookie = "__Host-KMKNKK=1234;Sercure;path=/"

Session

Session是在無狀態(tài)的HTTP協(xié)議下,服務(wù)端記錄用戶狀態(tài)時用于標(biāo)識具體用戶的機制税稼。它是在服務(wù)端保存的用來跟蹤用戶的狀態(tài)的數(shù)據(jù)結(jié)構(gòu),可以保存在文件垮斯、數(shù)據(jù)庫或者集群中郎仆。在瀏覽器關(guān)閉后這次的Session就消失了,下次打開不再擁有這個Session兜蠕。其實并不是Session消失了扰肌,而是Session ID變了,服務(wù)器端可能還是存著你上次的Session ID及其Session 信息熊杨,只是他們是無主狀態(tài)曙旭,也許一段時間后會被刪除。大多數(shù)的應(yīng)用都是用Cookie來實現(xiàn)Session跟蹤的晶府,第一次創(chuàng)建Session的時候桂躏,服務(wù)端會在HTTP協(xié)議中告訴客戶端,需要在Cookie里面記錄一個SessionID川陆,以后每次請求把這個會話ID發(fā)送到服務(wù)器

cookie和session的工作原理

由于http的無狀態(tài)性剂习,為了使某個域名下的所有網(wǎng)頁能夠共享某些數(shù)據(jù),session和cookie出現(xiàn)了较沪×廴疲客戶端訪問服務(wù)器的流程如下:

  • 首先,客戶端會發(fā)送一個http請求到服務(wù)器端尸曼。
  • 服務(wù)器端接受客戶端請求后们何,建立一個session,并發(fā)送一個http響應(yīng)到客戶端控轿,這個響應(yīng)頭冤竹,其中就包含Set-Cookie頭部拂封。該頭部包含了sessionId。Set-Cookie格式如下:
    Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
  • 在客戶端發(fā)起的第二次請求贴见,假如服務(wù)器給了set-Cookie烘苹,瀏覽器會自動在請求頭中添加cookie
  • 服務(wù)器接收請求,分解cookie片部,驗證信息镣衡,核對成功后返回response給客戶端


    image.png
cookie和session的區(qū)別
  • Session是在服務(wù)端保存的一個數(shù)據(jù)結(jié)構(gòu),用來跟蹤用戶的狀態(tài)档悠,這個數(shù)據(jù)可以保存在集群廊鸥、數(shù)據(jù)庫、文件中辖所,Cookie是客戶端保存用戶信息的一種機制惰说,用來記錄用戶的一些信息,也是實現(xiàn)Session的一種方式缘回。
  • Cookie安全性一般吆视,他人可通過分析存放在本地的Cookie并進(jìn)行Cookie欺騙。在安全性第一的前提下酥宴,選擇Session更優(yōu)啦吧。重要交互信息比如權(quán)限等就要放在Session中,一般的信息記錄放Cookie就好了拙寡。
  • 單個Cookie保存的數(shù)據(jù)不能超過4K授滓,很多瀏覽器都限制一個站點最多保存20個Cookie
  • 當(dāng)訪問增多時肆糕,Session會較大地占用服務(wù)器的性能般堆。考慮到減輕服務(wù)器性能方面诚啃,應(yīng)當(dāng)適時使用Cookie淮摔。
  • Session的運行依賴Session ID,而Session ID是存在 Cookie 中的始赎。也就是說噩咪,如果瀏覽器禁用了Cookie,Session也會失效(但是可以通過其它方式實現(xiàn),比如在url中傳遞Session ID,即sid=xxxx)
838172_1501942685861_37B4C735DA0DFFCC398F8BEBB1CEE5AE.png
注意:
  • cookie只是實現(xiàn)session的其中一種方案极阅。雖然是最常用的胃碾,但并不是唯一的方法。禁用cookie后還有其他方法存儲筋搏,比如放在url中
  • 現(xiàn)在大多都是Session + Cookie仆百,但是只用session不用cookie,或是只用cookie奔脐,不用session在理論上都可以保持會話狀態(tài)俄周∮跆郑可是實際中因為多種原因,一般不會單獨使用
    用session只需要在客戶端保存一個id峦朗,實際上大量數(shù)據(jù)都是保存在服務(wù)端建丧。如果全部用cookie,數(shù)據(jù)量大的時候客戶端是沒有那么多空間的波势。
  • 如果只用cookie不用session翎朱,那么賬戶信息全部保存在客戶端,一旦被劫持尺铣,全部信息都會泄露拴曲。并且客戶端數(shù)據(jù)量變大,網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)量也會變大
  • 簡而言之, session 有如用戶信息檔案表, 里面包含了用戶的認(rèn)證信息和登錄狀態(tài)等信息. 而 cookie 就是用戶通行證

token

token 也稱作令牌凛忿,由uid+time+sign[+固定參數(shù)]
token 的認(rèn)證方式類似于臨時的證書簽名, 并且是一種服務(wù)端無狀態(tài)的認(rèn)證方式, 非常適合于 REST API 的場景. 所謂無狀態(tài)就是服務(wù)端并不會保存身份認(rèn)證相關(guān)的數(shù)據(jù)澈灼。

組成

uid: 用戶唯一身份標(biāo)識
time: 當(dāng)前時間的時間戳
sign: 簽名, 使用 hash/encrypt 壓縮成定長的十六進(jìn)制字符串,以防止第三方惡意拼接
固定參數(shù)(可選): 將一些常用的固定參數(shù)加入到 token 中是為了避免重復(fù)查庫

存放

token在客戶端一般存放于localStorage店溢,cookie叁熔,或sessionStorage中。在服務(wù)器一般存于數(shù)據(jù)庫中

token認(rèn)證流程

token 的認(rèn)證流程與cookie很相似

  • 用戶登錄床牧,成功后服務(wù)器返回Token給客戶端荣回。
  • 客戶端收到數(shù)據(jù)后保存在客戶端
  • 客戶端再次訪問服務(wù)器,將token放入headers中
  • 服務(wù)器端采用filter過濾器校驗叠赦。校驗成功則返回請求數(shù)據(jù)驹马,校驗失敗則返回錯誤碼
token可以抵抗csrf革砸,cookie+session不行

假如用戶正在登陸銀行網(wǎng)頁除秀,同時登陸了攻擊者的網(wǎng)頁,且銀行網(wǎng)頁未對csrf攻擊進(jìn)行防護(hù)算利。攻擊者可以在網(wǎng)頁放一個表單册踩,該表單提交src為http://www.bank.com/api/transfer,body為count=1000&to=Tom效拭。倘若是session+cookie暂吉,用戶打開網(wǎng)頁的時候就已經(jīng)轉(zhuǎn)給Tom1000元了。因為form 發(fā)起的 POST 請求并不受到瀏覽器同源策略的限制缎患,因此可以任意地使用其他域的 Cookie 向其他域發(fā)送 POST 請求慕的,形成 CSRF 攻擊。在post請求的瞬間挤渔,cookie會被瀏覽器自動添加到請求頭中肮街。但token不同,token是開發(fā)者為了防范csrf而特別設(shè)計的令牌判导,瀏覽器不會自動添加到headers里嫉父,攻擊者也無法訪問用戶的token沛硅,所以提交的表單無法通過服務(wù)器過濾,也就無法形成攻擊绕辖。

localStorage和sessionStorage

兩者的共同點:
  • 存儲大小均為5M左右
  • 都有同源策略限制
  • 僅在客戶端中保存摇肌,不參與和服務(wù)器的通信
兩者的不同點:

1、生命周期 —— 數(shù)據(jù)可以存儲多少時間

  • localStorage: 存儲的數(shù)據(jù)是永久性的仪际,除非用戶人為刪除否則會一直存在围小。
  • sessionStorage: 與存儲數(shù)據(jù)的腳本所在的標(biāo)簽頁的有效期是相同的。一旦窗口或者標(biāo)簽頁被關(guān)閉弟头,那么所有通過 sessionStorage 存儲的數(shù)據(jù)也會被刪除吩抓。
    2、作用域 —— 誰擁有數(shù)據(jù)的訪問權(quán)
  • localStorage: 在同一個瀏覽器內(nèi)赴恨,同源文檔之間共享 localStorage 數(shù)據(jù)疹娶,可以互相讀取、覆蓋伦连。
  • sessionStorage: 與 localStorage 一樣需要同一瀏覽器同源文檔這一條件雨饺。不僅如此,sessionStorage 的作用域還被限定在了窗口中惑淳,也就是說额港,只有同一瀏覽器、同一窗口的同源文檔才能共享數(shù)據(jù)歧焦。

為了更好的理解sessionStorage,我們來看個例子:
例如你在瀏覽器中打開了兩個相同地址的頁面A移斩、B,雖然這兩個頁面的源完全相同,但是他們還是不能共享數(shù)據(jù)绢馍,因為他們是不同窗口中的向瓷。但是如果是一個窗口中,有兩個同源的iframe元素的話舰涌,這兩個iframe的 sessionStorage 是可以互通的猖任。

API
//sessionStorage用法相同
localStorage.setItem("name",1);   // 以"x"為名字存儲一個數(shù)值
localStorage.getItem("name");     // 獲取數(shù)值
localStorage.key(i);              // 獲取第i對的名字
localStorage.removeItem("name");  // 獲取該對的值
localStorage.clear();             // 全部刪除
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市瓷耙,隨后出現(xiàn)的幾起案子朱躺,更是在濱河造成了極大的恐慌,老刑警劉巖搁痛,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件长搀,死亡現(xiàn)場離奇詭異,居然都是意外死亡鸡典,警方通過查閱死者的電腦和手機源请,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人巢钓,你說我怎么就攤上這事病苗。” “怎么了症汹?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵硫朦,是天一觀的道長。 經(jīng)常有香客問我背镇,道長咬展,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任瞒斩,我火速辦了婚禮破婆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胸囱。我一直安慰自己祷舀,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布烹笔。 她就那樣靜靜地躺著裳扯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谤职。 梳的紋絲不亂的頭發(fā)上饰豺,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天,我揣著相機與錄音允蜈,去河邊找鬼冤吨。 笑死,一個胖子當(dāng)著我的面吹牛饶套,可吹牛的內(nèi)容都是我干的漩蟆。 我是一名探鬼主播,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼凤跑,長吁一口氣:“原來是場噩夢啊……” “哼爆安!你這毒婦竟也來了叛复?” 一聲冷哼從身側(cè)響起仔引,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎褐奥,沒想到半個月后咖耘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡撬码,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年儿倒,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,973評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡夫否,死狀恐怖彻犁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凰慈,我是刑警寧澤汞幢,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站微谓,受9級特大地震影響森篷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜豺型,卻給世界環(huán)境...
    茶點故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一仲智、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧姻氨,春花似錦钓辆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至抖韩,卻和暖如春蛀恩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背茂浮。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工双谆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人席揽。 一個月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓顽馋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親幌羞。 傳聞我的和親對象是個殘疾皇子寸谜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,982評論 2 361