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