Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

一文理清Session,Cookie和Token

eors 2021-09-10 18:08:42 阅读数:3996 评论数:0 点赞数:0 收藏数:0

前言

之前看了不少同類型的文章,對於Cookie和Session真是眾說紛紜,有的人說先有Cookie才有Session,也有的人說現有Session再有Cookie。我也說說我的理解,希望對大家有所幫助。 注:需要讀者對於Cookie/Session/Token有基本的了解。

Cookie和Session

說這倆之前,先說http,它是一個無狀態協議。 怎麼理解呢?就是說連續的兩次請求之間是沒有任何關聯的。這樣的好處是快速,壞處是想要把同個域名下的兩個頁面關聯起來,必須使用某些手段和工具。 這就引出了我們要說的Cookie和Session。 讓我們用文字+圖片了解一下客戶端訪問服務器的流程: • 首先,客戶端會發送一個http請求到服務器端; • 服務器端接受客戶端請求後,建立一個Session,並發送一個http響應到客戶端,這個響應頭,其中就包含Set-Cookie頭部。該頭部包含了SessionId; • 在客戶端發起的第二次請求,假如服務器給了Set-Cookie,瀏覽器會自動在請求頭中添加Cookie; • 服務器接收請求,分解Cookie,驗證信息,核對成功後返回response給客戶端。 這裏有幾點要注意的: • Cookie只是實現Session的其中一種方案。雖然是最常用的,但並不是唯一的方法。禁用Cookie後還有其他方法存儲,比如放在url中; • 單一使用Session不用Cookie,或者反過來只用Cookie不用Session,在理論上都可以保持會話狀態,只是實際操作中因為多種原因,大多都是Session + Cookie; • 用Session只需要在客戶端保存一個id,實際上大量數據都是保存在服務器端。如果全部用Cookie,數據量大的時候客戶端是沒有那麼多空間的; • 如果只用Cookie不用Session,那麼賬戶信息全部保存在客戶端,一旦被劫持,全部信息都會泄露。並且客戶端數據量變大,網絡傳輸的數據量也會變大。

簡單總結,就是Session 有點像用戶信息檔案錶, 裏面包含了用戶的認證信息和登錄狀態等信息,而 Cookie 就是用戶通行證。

Token

Token 也稱作令牌,由uid+time+sign(+固定參數)組成: • uid: 用戶唯一身份標識 • time: 當前時間的時間戳 • sign: 簽名, 使用 hash/encrypt 壓縮成定長的十六進制字符串,以防止第三方惡意拼接 • 固定參數(可選): 將一些常用的固定參數加入到 Token 中是為了避免重複查庫 Token 的認證方式類似於臨時的證書簽名, 並且是一種服務器端無狀態的認證方式, 非常適合於 REST API 的場景. 所謂無狀態就是服務器端並不會保存身份認證相關的數據。 Token在客戶端一般存放於LocalStorage,Cookie,或SessionStorage中。在服務器一般存於數據庫中。

Token認證流程

Token 的認證流程與Cookie很接近 • 用戶登錄,成功後服務器返回Token給客戶端; • 客戶端收到數據後保存在客戶端; • 客戶端再次訪問服務器,將Token放入Headers中; • 服務器端采用filter過濾器校驗。校驗成功則返回請求數據,校驗失敗則返回錯誤碼。

Cookie,Session和Token的區別

Token可以抵抗CSRF攻擊,Cookie+Session不行 我們假設一個場景: 用戶正在登陸銀行網頁,同時登陸了攻擊者Tom的網頁; 銀行網頁未對CSRF攻擊進行防護; Tom在網頁放了一個錶單,該錶單提交src為www.bank.com/api/transfe… 如果用的是Session+Cookie,用戶打開網頁的時候就已經被Tom轉走卡裏的錢了。因為form 發起的post請求並不受到瀏覽器同源策略的限制,因此可以任意地使用其他域的 Cookie 向其他域發送 post 請求,形成 CSRF 攻擊。在post請求的瞬間,Cookie會被瀏覽器自動添加到請求頭中。 但Token不同,Token是開發者為了防範CSRF而特別設計的令牌,瀏覽器不會自動添加到Headers裏,攻擊者也無法訪問用戶的Token,所以提交的錶單無法通過服務器過濾,也就無法形成攻擊。

分布式情况下的Session和Token

我們已經知道Session是有狀態的,一般存於服務器內存或硬盤中,當服務器采用分布式或集群時,Session就會面對負載均衡問題。 • 負載均衡多服務器的情况,不好確認當前用戶是否登錄,因為多服務器不共享Session。這個問題也可以將Session存在一個服務器中來解决,但是就不能完全達到負載均衡的效果。有辦法解决但是挺麻煩的。 而Token是無狀態的,Token字符串裏就保存了所有的用戶信息 • 客戶端登陸傳遞信息給服務器端,服務器端收到後把用戶信息加密(Token)傳給客戶端,客戶端將Token存放於LocalStroage等容器中。客戶端每次訪問都傳遞Token,服務器端解密Token,就知道這個用戶是誰了。通過cpu加解密,服務器端就不需要存儲Session占用存儲空間,就很好的解决負載均衡多服務器的問題了。 注:這個方法叫做JWT(Json Web Token)。

總結

• Cookie類似一個令牌,裝有SessionId,存儲在客戶端,瀏覽器通常會自動添加。 • Session存儲於服務器,可以理解為一個狀態列錶,擁有一個唯一識別符號SessionId,通常存放於Cookie中。服務器收到Cookie後解析出SessionId,再去Session列錶中查找,才能找到相應Session。同時Session依賴Cookie。 • Token可以說是一個無狀態的令牌,需要開發者手動添加。用戶信息被加密到Token字符串中,服務器收到Token後解密就可知道是哪個用戶。 • JWT只是一個跨域認證的方案。 撰寫 Eolinker:致力於API全生命周期開發管理的國產流行API工具。 參考文章 Cookie、Session、Token那點事兒 cookie,token驗證的區別 有了cookie為什麼需要session 徹底弄懂session,cookie,token CSRF Token的設計是否有其必要性 cookie,token,session三者的問題和解决方案 負載均衡集群中的session解决方案 JWT介紹 Json Web Token 入門教程

版权声明
本文为[eors]所创,转载请带上原文链接,感谢

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;

支付宝红包,每日可领