session,cookie,token
Cookie
簡介
Cookie 是由伺服器生成,傳送給瀏覽器,瀏覽器把 Cookie 以 kv 形式儲存到本地。瀏覽器每次向伺服器發出請求,就會自動附上這段資訊。每個 Cookie 的大小一般不能超過 4KB,一個 web 站點最多可以設定 20個 Cookie,一個瀏覽器最多可以設定 300個 Cookie。同時 Cookie 也具有時效性,超過設定的時效,系統就會自動清除。
用途
- 會話管理:記錄使用者的登入狀態,訪問狀態(例如導航,使用者的註冊流程等);
- 個性化資訊:記憶使用者相關的資訊(例如記憶上一次登入的使用者的QQ號碼)和使用者自定義的一些功能(例如google將搜尋設定:使用語言、每頁的條數等,儲存在一個COOKIE裡);
- 記錄使用者的行為:最典型的是公司的TCSS系統。它使用Cookie來記錄使用者的點選流和某個產品或商業行為的操作率和流失率。
缺點
- Cookie 會被附加在每個 HTTP 請求中,所以無形中增加了流量;
- 由於在 HTTP 請求中的 Cookie 是明文傳遞的,所以安全性成問題,除非用HTTPS;
- Cookie的大小限制在4KB左右,對於複雜的儲存需求來說是不夠用的。
Session
Session 就是“會話”,當用戶開啟某個 web 應用時,便與 web 伺服器產生一次 session。伺服器使用 session 把使用者的資訊臨時儲存在了伺服器上,使用者離開網站後 session 會被銷燬,相對 cookie 更安全。
cookie 和 session 執行流程
- 客戶端傳送一個http請求到伺服器端;
- 伺服器端接受客戶端請求後,建立一個session,並生成sessionID設定進Cookie頭併發送一個http響應到客戶端;
- 在客戶端發起的第二次請求,假如伺服器給了set-Cookie,瀏覽器會自動在請求頭中新增cookie;
- 伺服器接收請求,分解cookie,驗證資訊,核對成功後返回response給客戶端
Session 和 Cookie 一般都是結合使用的。用 session 只需要在客戶端儲存一個id,實際上大量資料都是儲存在服務端,所以當訪問增多,session 會比較佔用伺服器的效能。簡而言之, 將登陸資訊等重要資訊存放為 session,其他資訊如果需要保留,可以放在 cookie 中。
Token
token 也稱作令牌,由uid+time+sign[+固定引數]。token 的認證方式類似於臨時的證書籤名, 並且是一種服務端無狀態的認證方式, 所謂無狀態就是服務端並不會儲存身份認證相關的資料。
- uid: 使用者唯一身份標識;
- time: 當前時間的時間戳;
- sign: 簽名, 使用 hash/encrypt 壓縮成定長的十六進位制字串,以防止第三方惡意拼接;
- 固定引數(可選): 將一些常用的固定引數加入到 token 中是為了避免重複查庫。
token在客戶端一般存放於localStorage,cookie,或sessionStorage中。
token認證流程:
- 使用者登入,成功後伺服器返回Token給客戶端;
- 客戶端收到資料後儲存在客戶端;
- 客戶端再次訪問伺服器,將token放入headers中;
- 伺服器端採用filter過濾器校驗。校驗成功則返回請求資料,校驗失敗則返回錯誤碼。
token可以抵抗csrf,cookie+session不行
假如使用者正在登陸銀行網頁,同時登陸了攻擊者的網頁,並且銀行網頁未對csrf攻擊進行防護。攻擊者就可以在網頁放一個表單,該表單提交src為 http://www.bank.com/api/transfer ,body為count=1000&to=Tom。倘若是session+cookie,使用者開啟網頁的時候就已經轉給Tom1000元了.因為form 發起的 POST 請求並不受到瀏覽器同源策略的限制,因此可以任意地使用其他域的 Cookie 向其他域傳送 POST 請求,形成 CSRF 攻擊。在post請求的瞬間,cookie會被瀏覽器自動新增到請求頭中。但token不同,token是開發者為了防範csrf而特別設計的令牌,瀏覽器不會自動新增到headers裡,攻擊者也無法訪問使用者的token,所以提交的表單無法通過伺服器過濾,也就無法形成攻擊。
分散式情況下的session和token
我們已經知道session時有狀態的,一般存於伺服器記憶體或硬碟中,當伺服器採用分散式或叢集時,session就會面對負載均衡問題。
- 負載均衡多伺服器的情況,不好確認當前使用者是否登入,因為多伺服器不共享session。這個問題也可以將session存在一個伺服器中來解決,但是就不能完全達到負載均衡的效果。當今的幾種解決session負載均衡的方法。
而token是無狀態的,token字串裡就儲存了所有的使用者資訊
- 客戶端登陸傳遞資訊給服務端,服務端收到後把使用者資訊加密(token)傳給客戶端,客戶端將token存放於localStroage等容器中。客戶端每次訪問都傳遞token,服務端解密token,就知道這個使用者是誰了。通過cpu加解密,服務端就不需要儲存session佔用儲存空間,就很好的解決負載均衡多伺服器的問題了。這個方法叫做JWT(Json Web Token)
總結
- session儲存於伺服器,可以理解為一個狀態列表,擁有一個唯一識別符號sessionId,通常存放於cookie中。伺服器收到cookie後解析出sessionId,再去session列表中查詢,才能找到相應session。依賴cookie
- cookie類似一個令牌,裝有sessionId,儲存在客戶端,瀏覽器通常會自動新增。
- token也類似一個令牌,無狀態,使用者資訊都被加密到token中,伺服器收到token後解密就可知道是哪個使用者。需要開發者手動新增。
- jwt只是一個跨域認證的方案
原文地址: 徹底弄懂session,cookie,token