cookie,session,token作為面試必問題,很多同學能答個大概,但是又迷糊不清,希望本篇文章對大家有所幫助
什麼是無狀態呢?就是說這一次請求和上一次請求是沒有任何關係的,互不認識的,沒有關聯的。這種無狀態的的好處是快速。
cookie和session由於http的無狀態性,為了使某個域名下的所有網頁能夠共享某些數據,session和cookie出現了。客戶端訪問伺服器的流程如下
首先,客戶端會發送一個http請求到伺服器端。
伺服器端接受客戶端請求後,建立一個session,並發送一個http響應到客戶端,這個響應頭,其中就包含Set-Cookie頭部。該頭部包含了sessionId。Set-Cookie格式如下,具體請看Cookie詳解
Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
在客戶端發起的第二次請求,假如伺服器給了set-Cookie,瀏覽器會自動在請求頭中添加cookie
伺服器接收請求,分解cookie,驗證信息,核對成功後返回response給客戶端
注意cookie只是實現session的其中一種方案。雖然是最常用的,但並不是唯一的方法。禁用cookie後還有其他方法存儲,比如放在url中
現在大多都是Session + Cookie,但是只用session不用cookie,或是只用cookie,不用session在理論上都可以保持會話狀態。可是實際中因為多種原因,一般不會單獨使用
用session只需要在客戶端保存一個id,實際上大量數據都是保存在服務端。如果全部用cookie,數據量大的時候客戶端是沒有那麼多空間的。
如果只用cookie不用session,那麼帳戶信息全部保存在客戶端,一旦被劫持,全部信息都會洩露。並且客戶端數據量變大,網絡傳輸的數據量也會變大
cookie和session通俗小結簡而言之, session 有如用戶信息檔案表, 裡面包含了用戶的認證信息和登錄狀態等信息. 而 cookie 就是用戶通行證
token定義token 也稱作令牌,由uid+time+sign[+固定參數]
token 的認證方式類似於臨時的證書籤名, 並且是一種服務端無狀態的認證方式, 非常適合於 REST API 的場景. 所謂無狀態就是服務端並不會保存身份認證相關的數據。
token在客戶端一般存放於localStorage,cookie,或sessionStorage中。在伺服器一般存於資料庫中
token認證流程token 的認證流程與cookie很相似
token可以抵抗csrf,cookie+session不行因為form 發起的 POST 請求並不受到瀏覽器同源策略的限制,因此可以任意地使用其他域的 Cookie 向其他域發送 POST 請求,形成 CSRF 攻擊。在post請求的瞬間,cookie會被瀏覽器自動添加到請求頭中。但token不同,token是開發者為了防範csrf而特別設計的令牌,瀏覽器不會自動添加到headers裡,攻擊者也無法訪問用戶的token,所以提交的表單無法通過伺服器過濾,也就無法形成攻擊。
分布式情況下的session和token我們已經知道session時有狀態的,一般存於伺服器內存或硬碟中,當伺服器採用分布式或集群時,session就會面對負載均衡問題。
而token是無狀態的,token字符串裡就保存了所有的用戶信息
總結session存儲於伺服器,可以理解為一個狀態列表,擁有一個唯一識別符號sessionId,通常存放於cookie中。伺服器收到cookie後解析出sessionId,再去session列表中查找,才能找到相應session。依賴cookie
cookie類似一個令牌,裝有sessionId,存儲在客戶端,瀏覽器通常會自動添加。
token也類似一個令牌,無狀態,用戶信息都被加密到token中,伺服器收到token後解密就可知道是哪個用戶。需要開發者手動添加。
jwt只是一個跨域認證的方案
補充:JWT
JWT就是token的一種實現方式,並且基本是java web領域的事實標準。
JWT全稱是JSON Web Token。基本可以看出是使用JSON格式傳輸token
JWT 由 3 部分構成:
Header :描述 JWT 的元數據。定義了生成籤名的算法以及 Token 的類型。Payload(負載):用來存放實際需要傳遞的數據Signature(籤名):伺服器通過Payload、Header和一個密鑰(secret)使用 Header 裡面指定的籤名算法(默認是 HMAC SHA256)生成。流程:
在基於 Token 進行身份驗證的的應用程式中,用戶登錄時,伺服器通過Payload、Header和一個密鑰(secret)創建令牌(Token)並將 Token 發送給客戶端,
然後客戶端將 Token 保存在 Cookie 或者 localStorage 裡面,以後客戶端發出的所有請求都會攜帶這個令牌。你可以把它放在 Cookie 裡面自動發送,但是這樣不能跨域,所以更好的做法是放在 HTTP Header 的 Authorization欄位中:Authorization: 你的Token。
往期推薦:
性能測試之nginx訪問日誌分析