這里是修真院前端小課堂,本篇分析的主題是
【什么是session?什么是cookie?session和cookie有什么區別?】
每篇分享文從
【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴展思考】【更多討論】【參考文獻】
八個方面深度解析前端知識/技能,本篇分享的是:
【什么是session?什么是cookie?session和cookie有什么區別?】
什么是SESSION?什么是COOKIE?SESSION和COOKIE有什么區別? 什么場景適用於SESSION?什么場景適用於COOKIE?
1.背景介紹
通過例子簡單引入
星巴克開始優惠活動,每消費10杯咖啡,會免費贈送1杯。考慮到一個人一次性消費10杯咖啡幾乎不可能,所以需要采取某種方式來記錄顧客的消費數量。
解決方案
1)店員很厲害,每個顧客的消費記錄都記得一清二楚;
2)分給顧客一張卡片,每消費一次記錄一次;
3)發給顧客一張卡片,上面有卡號,顧客每消費一次,由店員在操作機上記錄一次。
分析:方案一的可執行性幾乎為0。方案二和方案三我們都見過。 而方案二和三正是對應的客戶端記錄和服務端記錄。與之相對應的正是cookie和session。 好了,我們進入正題。
由於HTTP是一種無狀態協議,服務器沒有辦法單單從網絡連接上面知道訪問者的身份,為了解決這個問題,就誕生了Cookie
Cookie實際上是一小段的文本信息。客戶端請求服務器,如果服務器需要記錄該用戶狀態,就使用response向客戶端瀏覽器頒發一個Cookie
客戶端瀏覽器會把Cookie保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。服務器檢查該Cookie,
以此來辨認用戶狀態。服務器還可以根據需要修改Cookie的內容。
實際就是頒發一個通行證,每人一個,無論誰訪問都必須攜帶自己通行證。這樣服務器就能從通行證上確認客戶身份了。這就是Cookie的工作原理
cookie 可以讓服務端程序跟蹤每個客戶端的訪問,但是每次客戶端的訪問都必須傳回這些Cookie,如果 Cookie 很多,這無形地增加了客戶端與服務端的數據傳輸量,
而 Session 的出現正是為了解決這個問題。同一個客戶端每次和服務端交互時,不需要每次都傳回所有的 Cookie 值,而是只要傳回一個 ID,這個 ID 是客戶端第一次訪問服務器的時候生成的, 而且每個客戶端是唯一的。這樣每個客戶端就有了一個唯一的 ID,客戶端只要傳回這個 ID 就行了,這個 ID 通常是 NANE 為JSESIONID 的一個 Cookie。
2.知識剖析
cookie機制
cookie的內容主要包括name(名字)、value(值)、maxAge(失效時間)、path(路徑),domain(域)和secure
name:cookie的名字,一旦創建,名稱不可更改。
value:cookie的值,如果值為Unicode字符,需要為字符編碼。如果為二進制數據,則需要使用BASE64編碼.
maxAge:cookie失效時間,單位秒。如果為正數,則該cookie在maxAge后失效。如果為負數,該cookie為臨時cookie,關閉瀏覽器即失效, 瀏覽器也不會以任何形式保存該cookie。如果為0,表示刪除該cookie。默認為-1
path:該cookie的使用路徑。如果設置為"/sessionWeb/",則只有ContextPath為“/sessionWeb/”的程序可以訪問該cookie。如果設置為“/”,則本域名下ContextPath都可以訪問該cookie。
domain:域.可以訪問該Cookie的域名。第一個字符必須為".",如果設置為".google.com",則所有以"google.com結尾的域名都可以訪問該cookie",如果不設置,則為所有域名
secure:該cookie是否僅被使用安全協議傳輸。
Session機制
Session機制是一種服務端的機制,服務器使用一種類似散列表的結構來保存信息。
當程序需要為某個客戶端的請求創建一個session的時候,服務器首先檢查這個客戶端里的請求里是否已包含了一個session標識--sessionID,
如果已經包含一個sessionID,則說明以前已經為此客戶端創建過session,服務器就按照sessionID把這個session檢索出來使用
如果客戶端請求不包含sessionID,則為此客戶端創建一個session並且聲稱一個與此session相關聯的sessionID,
sessionID的值應該是一個既不會重復,又不容易被找到規律以仿造的字符串(服務器會自動創建),這個sessionID將被在本次響應中返回給客戶端保存。
3.常見問題
使用cookie的弊端
使用session的弊端
cookie和session的區別
4.解決方案
使用cookie的缺點
如果瀏覽器使用的是cookie,那么所有的數據都保存在瀏覽器端,
cookie可以被用戶禁止
cookie不安全(對於敏感數據,需要加密)
cookie只能保存少量的數據(大約是4k),cookie的數量也有限制(大約是幾百個),不同瀏覽器設置不一樣,反正都不多
cookie只能保存字符串
對服務器壓力小
使用session的缺點
一般是寄生在Cookie下的,當Cookie被禁止,Session也被禁止
當然可以通過url重寫來擺脫cookie
當用戶訪問量很大時,對服務器壓力大
我們現在知道session是將用戶信息儲存在服務器上面,如果訪問服務器的用戶越來越多,那么服務器上面的session也越來越多, session會對服務器造成壓力,影響服務器的負載.如果Session內容過於復雜,當大量客戶訪問服務器時還可能會導致內存溢出。
用戶信息丟失, 或者說用戶訪問的不是這台服務器的情況下,就會出現數據庫丟失.
cookie和session的區別
具體來說cookie機制采用的是在客戶端保持狀態的方案,而session機制采用的是在服務器端保持狀態的方案。同時我們也看到, 由於采用服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要借助於cookie機制來達到保存標識的目的
cookie不是很安全,別人可以分析存放在本地的cookie並進行cookie欺騙,考慮到安全應當使用session
session會在一定時間內保存在服務器上。當訪問增多,會比較占用你服務器的性能,考慮到減輕服務器性能方面,應當使用cookie
單個cookie保存的數據不能超過4k,很多瀏覽器都限制一個站點最多保存20個cookie。
可以將登陸信息等重要信息存放為session。
5.擴展思考
一般的驗證方式
1.生成3個COOKIE,分別使用用戶名,登錄時間,用戶名+登錄時間DES加密后的密文
2.使用COOKIE與SESSION進行比對驗證
3.使用JWT生成TOKEN,解密出被加密的部分進行驗證。
JSON Web Token(JWT)是一個開放的標准(RFC7519),它定義了一個緊湊且自包含的方式,用於在各方之間以JSON對象安全地傳輸信息。
一個JWT實際上就是一個字符串,它由三部分組成,頭部、載荷與簽名。
JWT的頭部用於描述關於該JWT的最基本的信息,例如其類型以及簽名所用的算法等。這也可以被表示成一個JSON對象。
"typ":"JWT",
"alg":"HS256"
當然頭部要進行BASE64編碼
簽名(Signature)
將上面的兩個編碼后的字符串都用句號.連接在一起(頭部在前)例如頭部使用base64編碼后為123.456
我們將上面拼接完的字符串用HS256算法進行加密。在加密的時候,還需要我們自己提供一個密鑰(secret)。 得到789.
將他們完全拼在一起,我們就得到了完整的JWT"123.456.789" 在我們的請求URL中會帶上這串JWT字符串
載荷
iss: 該JWT的簽發者, 是否使用是可選的;
sub: 該JWT所面向的用戶,是否使用是可選的;
aud: 接收該JWT的一方, 是否使用是可選的;
exp(expires): 什么時候過期,這里是一個Unix時間戳,是否使用是可選的;
iat(issued at): 在什么時候簽發的(UNIX時間),是否使用是可選的;
nbf (Not Before):如果當前時間在nbf里的時間之前,則Token不被接受;一般都會留一些余地,比如幾分鍾;,是否使用是可選的;
JWT的Token認證
對Token認證的五點認識
對Token認證機制有5點直接注意的地方:
一個Token就是一些信息的集合;
在Token中包含足夠多的信息,以便在后續請求中減少查詢數據庫的幾率;
服務端需要對cookie和HTTP Authrorization Header進行Token信息的檢查;
基於上一點,你可以用一套token認證代碼來面對瀏覽器類客戶端和非瀏覽器類客戶端;
因為token是被簽名的,所以我們可以認為一個可以解碼認證通過的token是由我們系統發放的,其中帶的信息是合法有效的;
Token機制相對於Cookie機制又有什么好處呢?
支持跨域訪問:Cookie是不允許垮域訪問,這一點對Token機制是不存在的,前提是傳輸的用戶認證信息通過HTTP頭傳輸.
無狀態(也稱:服務端可擴展行):Token機制在服務端不需要存儲session信息,因為Token 自身包含了所有登錄用戶的信息,只需要在客戶端的cookie或本地介質存儲狀態信息.
更適用CDN: 可以通過內容分發網絡請求你服務端的所有資料(如:javascript,HTML,圖片等),而你的服務端只要提供API即可.
去耦: 不需要綁定到一個特定的身份驗證方案。Token可以在任何地方生成,只要在你的API被調用的時候,你可以進行Token生成調用即可.
更適用於移動應用: 當你的客戶端是一個原生平台(iOS, Android,Windows 8等)時,Cookie是不被支持的(你需要通過Cookie容器進行處理),這時采用Token認證機制就會簡單得多。
CSRF:因為不再依賴於Cookie,所以你就不需要考慮對CSRF(跨站請求偽造)的防范。
性能: 一次網絡往返時間(通過數據庫查詢session信息)總比做一次HMACSHA256計算 的Token驗證和解析要費時得多.
不需要為登錄頁面做特殊處理:如果你使用Protractor 做功能測試的時候,不再需要為登錄頁面做特殊處理.
基於標准化:你的API可以采用標准化的 JSON Web Token (JWT). 這個標准已經存在多個后端庫(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如:Firebase,Google,Microsoft).
6.參考文獻
百度
http://blog.csdn.net/fangaoxin/article/details/6952954/
http://www.cnblogs.com/xiekeli/p/5607107.html
由於HTTP是一種無狀態協議,服務器沒有辦法單單從網絡連接上面知道訪問者的身份,為了解決這個問題,就誕生了Cookie
Cookie實際上是一小段的文本信息。客戶端請求服務器,如果服務器需要記錄該用戶狀態,就使用response向客戶端瀏覽器頒發一個Cookie
客戶端瀏覽器會把Cookie保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。服務器檢查該Cookie,
以此來辨認用戶狀態。服務器還可以根據需要修改Cookie的內容。
實際就是頒發一個通行證,每人一個,無論誰訪問都必須攜帶自己通行證。這樣服務器就能從通行證上確認客戶身份了。這就是Cookie的工作原理
cookie可以讓服務端程序跟蹤每個客戶端的訪問,但是每次客戶端的訪問都必須傳回這些 Cookie,如果 Cookie 很多,這無形地增加了客戶端與服務端的數據傳輸量,
而 Session 的出現正是為了解決這個問題。同一個客戶端每次和服務端交互時,不需要每次都傳回所有的 Cookie 值,而是只要傳回一個 ID,這個 ID 是客戶端第一次訪問服務器的時候生成的, 而且每個客戶端是唯一的。這樣每個客戶端就有了一個唯一的 ID,客戶端只要傳回這個 ID 就行了,這個 ID 通常是 NANE 為JSESIONID 的一個 Cookie。
原文:https://blog.csdn.net/jnshu_it/article/details/79894570