彻底搞懂Cookie、Session、JWT和Token
文章目錄
- 引入:http是一個無狀態協議?怎么解決呢?
- 一、Cookie和Session
- 1.1 cookie 注意事項:
- 1.2 cookie 重要的屬性
- 1.3 session 注意事項:
- 1.4 Cookie 和 Session 的區別:
- 二、token(令牌)
- 2.1 token優勢
- 2.2 token 的身份驗證流程
- 三、基于JWT實現的Token認證方案
- 3.1 JWT組成部分
- 3.1.1 Header:標頭
- 3.1.2 Payload:有效載荷
- 3.1.3 Payload:簽名
- 3.2 什么時候應該使用 JWT?
- 3.3 JWT和Token有什么關系?
引入:http是一個無狀態協議?怎么解決呢?
無狀態是指協議對于事務處理沒有記憶能力。缺少狀態意味著如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。HTTP無狀態的特性嚴重阻礙了這些應用程序的實現,畢竟交互是需要承前啟后的,簡單的購物車程序也要知道用戶到底在之前選擇了什么商品。于是,兩種用于保持HTTP連接狀態的技術就應運而生了,一個是 Cookie,而另一個則是 Session。
一、Cookie和Session
cookie中可以用來保存服務端返回的一些用戶信息的,每一次的請求,都會攜帶這些cookie。服務端從請求頭中取到cookie中的信息,就可以識別本次請求的來源,http就變成有狀態的了。
由于采用服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要借助于cookie機制來達到保存標識的目的。cookie不是很安全,別人可以分析存放在本地的cookie并進行cookie欺騙,考慮到安全應當使session, session會在一定時間內保存在服務器上。當訪問增多,會比較占用你服務器的性能,考慮到減輕服務器性能方面,應當使用cookie
1.1 cookie 注意事項:
1、cookie存放在客戶端(瀏覽器端),所以是不安全的,人為可以清除。cookie 是服務器發送到用戶瀏覽器并保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶并發送到服務器上。
2、cookie有過期時間設定。如果不設置過期時間,說明這個cookie就是當前瀏覽器的會話時間,瀏覽器關了,cookie就不存在了。如果有過期時間,cookie就會存儲到硬盤上,瀏覽器關閉不影響cookie。下次打開瀏覽器,cookie還存在
3、cookie可以被用戶禁止
4、cookie有大小的限制,一個瀏覽器能創建的 Cookie 數量最多為 300 個,并且每個不能超過 4KB,每個 Web 站點能設置的 Cookie 總數不能超過 20 個。
5、cookie 是不可跨域的: 每個 cookie 都會綁定單一的域名,無法在別的域名下獲取使用,一級域名和二級域名之間是允許共享使用的(靠的是 domain)。
1.2 cookie 重要的屬性
| String name | 該Cookie的名稱。Cookie一旦創建,名稱便不可更改 ,必須是字符串類型 |
| Object value | 該Cookie的值。如果值為Unicode字符,需要為字符編碼。如果值為二進制數據,則需要使用BASE64編碼 |
| int maxAge | 該Cookie失效的時間,單位秒。如果為正數,則該Cookie在maxAge秒之后失效。如果為負數,該Cookie為臨時Cookie,關閉瀏覽器即失效,瀏覽器也不會以任何形式保存該Cookie。如果為0,表示刪除該Cookie。默認為–1。比expires好用 |
| int expires | 設置Cookie過期時間,在設置的某一個時間后該cookie就會失效。 |
| boolean secure | 該Cookie是否僅被使用安全協議傳輸。安全協議。安全協議有HTTPS,SSL等,在網絡上傳輸數據之前先將數據加密。默認為false。**當secure值為true時,**cookie在HTTP中是無效的,在HTTPS中才有效 |
| String path | 該Cookie的使用路徑。如果設置為“/love/”,則只有contextPath為“/love”的程序可以訪問該Cookie。如果設置為“/”,則本域名下contextPath都可以訪問該Cookie。注意最后一個字符必須為“/” |
| String domain | 決定該cookie作用在哪個域。默認是當前域名 |
| int version | 該Cookie使用的版本號。0表示遵循Netscape的Cookie規范,1表示遵循W3C的RFC 2109規范 |
| HttpOnly | 該cookie不能通過js讀取,但還是能通過Application中手動修改cookie,所以只是在一定程度上防止XSS攻擊,并不是絕對的安全 |
1.3 session 注意事項:
1、session是將用戶信息儲存在服務器上面,如果訪問服務器的用戶越來越多,那么服務器上面的session也越來越多, session會對服務器造成壓力,影響服務器的負載.如果Session內容過于復雜,當大量客戶訪問服務器時還可能會導致內存溢出。
2、用戶信息丟失, 或者說用戶訪問的不是這臺服務器的情況下,就會出現數據庫丟失。這就是它的弊端。現在有一些技術,例如session共享、iphash、session持久等也可以解決上述問題。
3、當Cookie被禁止,Session也被禁止。cookie只是實現session的其中一種方案。雖然是最常用的,但并不是唯一的方法。禁用cookie后還有其他方法存儲,比如放在url中。
4、session 是基于 cookie 實現的,session 存儲在服務器端,sessionId 會被存儲到客戶端的cookie 中
根據以上流程我們可以看出,SessionID 是連接 Cookie 和 Session 的一道橋梁,大部分系統也是根據此原理來驗證用戶登錄狀態。但這種模式最大的問題是,沒有分布式架構,無法支持橫向擴展。如果使用一個服務器,該模式完全沒有問題。但是,如果它是服務器群集或面向服務的跨域體系結構的話,則需要一個統一的session數據庫庫來保存會話數據實現共享,這樣負載均衡下的每個服務器才可以正確的驗證用戶身份。
解決這個問題我們可以使用token,具體看下面對token的講解
1.4 Cookie 和 Session 的區別:
根據上面的解釋,我們在來最終總結一下它們大體的區別:
安全性: Session 比 Cookie 安全,Session 是存儲在服務器端的,Cookie 是存儲在客戶端的。
存取值的類型不同:Cookie 只支持存字符串數據,Session 可以存任意數據類型。
有效期不同: Cookie 可設置為長時間保持,比如我們經常使用的記住我(默認登錄)等功能,Session 一般失效時間較短,客戶端關閉(默認情況下)或者 Session 超時都會失效。
存儲大小不同: 單個 Cookie 保存的數據不能超過 4K,Session 可存儲數據遠高于 Cookie,但是當訪問量過多,會占用過多的服務器資源。
注意點:
現在大多都是Session + Cookie,但是只用session不用cookie,或是只用cookie,不用session在理論上都可以保持會話狀態。可是實際中因為多種原因,一般不會單獨使用,如果只用cookie不用session,那么賬戶信息全部保存在客戶端,一旦被劫持,全部信息都會泄露。并且客戶端數據量變大,網絡傳輸的數據量也會變大。
用session只需要在客戶端保存一個id,實際上大量數據都是保存在服務端。如果全部用cookie,數據量大的時候客戶端是沒有那么多空間的
簡而言之, session 就像用戶信息表, 里面包含了用戶的信息(姓名、狀態等等). 而 cookie 就是用戶通行證
二、token(令牌)
Token顧名思義就是令牌、憑證、鑰匙,只有這把鑰匙,你才能打開門。Token一般都是服務端生成,比如一個web系統,用戶登錄的時候,服務端校驗用戶名密碼通過以后,會生成一個token,然后將token返回給客戶端,客戶端會將token保存下來(放到 HTTP 的 Header 里), 后續所有的請求都會攜帶這個token。服務端會判斷當前token是否存在已經是否過期。如果token不存在或者過期就會拒絕本次請求。
簡單 token 的組成: uid(用戶唯一的身份標識)、time(當前時間的時間戳)、sign(簽名,token 的前幾位以哈希算法壓縮成的一定長度的十六進制字符串)
2.1 token優勢
1. Token 完全由應用管理,所以它可以避開同源策略
2. 安全性。Token 可以避免 CSRF攻擊(因為不需要 cookie 了)
CSRF攻擊(跨站請求偽造):攻擊者盜用了你的身份,以你的名義發送惡意請求。CSRF能夠做的事情包括:以你名義發送郵件,發消息,盜取你的賬號,甚至于購買商品,虛擬貨幣轉賬…造成的問題包括:個人隱私泄露以及財產安全。(CSRF攻擊具體是什么大家如果想要了解可以評論區討論哦)
3.無狀態、可擴展,可以在多個服務間共享
4.多平臺跨域:CORS(跨域資源共享)對應用程序和服務進行擴展的時候,需要介入各種各種的設備和應用程序。只要用戶有一個通過了驗證的token,數據和資源就能夠在任何域上被請求到。
2.2 token 的身份驗證流程
三、基于JWT實現的Token認證方案
創建token的時候,我們可以設定一些選項。但是標準的用法會在JSON Web Tokens簡稱JWT體現。
JSON Web Token(JWT)是目前最流行的跨域身份驗證解決方案。
3.1 JWT組成部分
JSON Web Tokens令牌以緊湊的形式由三部分組成,這些部分由點 (. )分隔,分別是:
Header:標頭
Payload: 有效載荷
Signature: 簽名
該對象為一個很長的字符串,字符之間通過"."分隔符分為三個子串。
每一個子串表示了一個功能塊,總共有以下三個部分:JWT頭、有效載荷和簽名
3.1.1 Header:標頭
標頭通常由兩部分組成:令牌的類型(即JWT)和所使用的簽名算法,例如HMAC SHA256或RSA。
例如:
3.1.2 Payload:有效載荷
有效載荷部分,是JWT的主體內容部分,也是一個JSON對象,包含需要傳遞的數據。 JWT指定七個默認
字段供選擇。
iss:發行人
exp:到期時間
sub:主題
aud:用戶
nbf:在此之前不可用
Iat:發布時間
jti:JWT ID用于標識該JWT
除以上默認字段外,我們還可以自定義私有字段,有效負載示例可以是:
{ "sub": "9876543210", "name": "Mr Fen", "admin": true 請注意,默認情況下JWT是未加密的,任何人都可以解讀其內容,因此不要構建隱私信息字段,存放保密信息,以防止信息泄露。 }3.1.3 Payload:簽名
要創建簽名部分,您必須獲取編碼的頭、編碼的負載、密鑰、頭中指定的算法,并對其進行簽名。
例如,如果要使用HMAC SHA256算法,則將通過以下方式創建簽名:
3.2 什么時候應該使用 JWT?
1、身份驗證,這是使用JWT的最常見方案。一旦用戶登錄,每個后續請求將包括JWT,從而允許用戶訪問該令牌允許的路由,服務和資源。單一登錄是當今廣泛使用JWT的一項功能,因為它的開銷很小并且可以在不同的域中輕松使用。
2、信息交換,JWT令牌是在各方之間安全地傳輸信息的一種好方法。因為可以對JWT進行簽名(例如,使用公鑰/私鑰對),所以您可以確定發件人是本人。另外,由于簽名是使用標頭和有效負載計算的,因此您還可以驗證內容是否未被篡改。
3.3 JWT和Token有什么關系?
token是按照一定規則生成的字符串,包含用戶信息。
一般我們會采用標準的用法JWT。
JWT就是給我們規定好了規則,使用JWT可以生成字符串,包含用戶信息。
總結
以上是生活随笔為你收集整理的彻底搞懂Cookie、Session、JWT和Token的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AI理论知识整理(17)-子式,非奇异,
- 下一篇: python3精要(1)-python特