Cookie、Session和Token(学习笔记)
HTTP協(xié)議本身是無狀態(tài)的,所以需要一個標(biāo)志來對用戶身份進(jìn)行驗證
身份驗證方式
- 基于cookie的身份驗證
- Cookie
- Session
- 應(yīng)用場景
- CSRF
- 基于token的身份驗證
- CORS
- token相對于cookie的優(yōu)勢
基于cookie的身份驗證
Cookie
???????Cookie 是客戶端的存儲空間,由瀏覽器來維持。Cookie 會根據(jù)從服務(wù)器端發(fā)送的響應(yīng)報文內(nèi)的一個叫做 Set-Cookie 的首部字段信息,通知客戶端保存 Cookie,當(dāng)下次客戶端再往該服務(wù)器發(fā)送請求時,客戶端會自動在請求報文中加入 Cookie 值后發(fā)送出去。
??????? Cookie 是服務(wù)器生成并發(fā)送給客戶端,且由客戶端來保存的。每次請求都需要加上 Cookie。服務(wù)器端收到客戶端發(fā)送的 Cookie 后,從數(shù)據(jù)庫中尋找相應(yīng)的sessionid,檢查究竟是從哪一個客戶端發(fā)來的連接請求,得到狀態(tài)信息。
單個Cookie 在客戶端的限制是3K,就是說一個站點在客戶端存放的COOKIE不能超過3K
Session
??????? Session 保存在服務(wù)器中,使用Cookie 作為識別標(biāo)志。HTTP協(xié)議是無狀態(tài)的,Session 不能依據(jù)HTTP連接來判斷是否為同一客戶,因此服務(wù)器向客戶端瀏覽器發(fā)送一個名為 JSESSIONID 的 Cookie,它的值為該 Session 的 id(即放在HTTP響應(yīng)報文頭部信息里的Set-Cookie)。Session依據(jù)該 Cookie 來識別是否為同一用戶。
???????基于cookie的驗證是有狀態(tài)的,就是說驗證或者會話信息必須同時在客戶端和服務(wù)端保存。這個信息服務(wù)端一般在數(shù)據(jù)庫中記錄,而前端會保存在cookie中。
應(yīng)用場景
基于cookie的身份驗證方式很容易受到CSRF(防跨站請求偽造)攻擊,因此需要使用基于token的身份驗證方式
CSRF
???????跨站請求偽造(英語:Cross-site request forgery),也被稱為 one-click attack 或者 session riding,通常縮寫為 CSRF 或者 XSRF, 是一種挾制用戶在當(dāng)前已登錄的Web應(yīng)用程序上執(zhí)行非本意的操作的攻擊方法。
攻擊過程舉例:
???????假設(shè)你已經(jīng)通過銀行的驗證并且cookie中存在驗證信息,同時銀行網(wǎng)站沒有CSRF保護(hù)。一旦用戶點了這個圖片(連接為【http://bank.com?withdraw=1000&to=tom】),就很有可能從銀行賬戶向tom轉(zhuǎn)1000塊錢。
防止CSRF攻擊的方式:
?如果銀行網(wǎng)站使用了token作為驗證手段,攻擊者將無法通過上面的鏈接轉(zhuǎn)走你的錢。(因為攻擊者無法獲取正確的token)
詳見怎么防止跨站請求偽造攻擊(CSRF)?
基于token的身份驗證
???????當(dāng)討論基于token的身份驗證時,一般都是說的JSON Web Tokens(JWT)。雖然有著很多不同的方式實現(xiàn)token,但是JWT已經(jīng)成為了事實上的標(biāo)準(zhǔn),所以后面會將JWT和token混用。
???????請求登錄時,token和sessionId原理相同,是對key和key對應(yīng)的用戶信息進(jìn)行加密后的加密字符,登錄成功后,會在響應(yīng)主體中將{token:‘字符串’}返回給客戶端。客戶端通過cookie、sessionStorage、localStorage都可以進(jìn)行存儲。再次請求時不會默認(rèn)攜帶,需要在請求攔截器位置給請求頭中添加認(rèn)證字段Authorization攜帶token信息,服務(wù)器端就可以通過token信息查找用戶登錄狀態(tài)。
???????JWT是一種無狀態(tài)的認(rèn)證機(jī)制,因為用戶狀態(tài)永遠(yuǎn)不會保存在服務(wù)器內(nèi)存中。服務(wù)器不記錄哪些用戶已登陸或者已經(jīng)發(fā)布了哪些JWT。對服務(wù)器的每個請求都需要帶上驗證請求的token。該標(biāo)記既可以加在header中,可以在POST請求的主體中發(fā)送,也可以作為查詢參數(shù)發(fā)送。服務(wù)器的受保護(hù)路由將在授權(quán)頭中檢查有效的JWT,如果存在,則允許用戶訪問受保護(hù)的資源。由于JWT是自說明的,包含了所有必要的信息,這就減少了多次查詢數(shù)據(jù)庫的需要。
???????這樣可以完全依賴無狀態(tài)的數(shù)據(jù)API,甚至可以向下游服務(wù)發(fā)出請求。API的作用域并不重要,因此跨源資源共享(CORS)不會是一個問題,因為它不使用Cookie。
CORS
??CORS是一個W3C標(biāo)準(zhǔn),全稱是"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨源服務(wù)器,發(fā)出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。
瀏覽器將CORS請求分成兩類:
- 簡單請求(simple request)
? 對于簡單請求,瀏覽器直接發(fā)出CORS請求。具體來說,就是在頭信息之中,增加一個Origin字段用來說明,本次請求來自哪個源(協(xié)議 + 域名 + 端口)。服務(wù)器根據(jù)這個值,決定是否同意這次請求:- 如果Origin指定的源,不在許可范圍內(nèi),服務(wù)器會返回一個正常的HTTP回應(yīng);
- 如果Origin指定的域名在許可范圍內(nèi),服務(wù)器返回的響應(yīng),會多出幾個頭信息字段。
- 非簡單請求(not-so-simple request)
??非簡單請求是那種對服務(wù)器有特殊要求的請求,比如請求方法是PUT或DELETE,或者Content-Type字段的類型是application/json。
??非簡單請求的CORS請求,會在正式通信之前,增加一次HTTP查詢請求,稱為"預(yù)檢"請求(preflight。
??瀏覽器先詢問服務(wù)器,當(dāng)前網(wǎng)頁所在的域名是否在服務(wù)器的許可名單之中,以及可以使用哪些HTTP動詞和頭信息字段。只有得到肯定答復(fù),瀏覽器才會發(fā)出正式的XMLHttpRequest請求,否則就報錯。
?? "預(yù)檢"請求用的請求方法是OPTIONS,表示這個請求是用來詢問的。頭信息里面,關(guān)鍵字段是Origin,表示請求來自哪個源。
詳見 跨域資源共享 CORS 詳解.
token相對于cookie的優(yōu)勢
服務(wù)器唯一的工作就是在成功的登陸請求上簽署token,并驗證傳入的token是否有效。
使用token,使得用從myapp.com獲取的授權(quán)向myservice1.com和myservice2.com獲取服務(wù)成為可能。
參考:
token和session的區(qū)別 .
Cookie和Token.
前后端分離 token和cookie對比.
總結(jié)
以上是生活随笔為你收集整理的Cookie、Session和Token(学习笔记)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hadoop——MapReduce相关e
- 下一篇: 程序员偷看了老板的微信分组,惊呆了……