cookie、session、token的區別(分享)

http協議是無狀態的

很久很久以前,Web 基本上就是文檔的瀏覽而已, 既然是瀏覽,作爲服務器, 不需要記錄誰在某一段時間裏都瀏覽了什麼文檔,每次請求都是一個新的HTTP協議, 就是請求加響應, 尤其是我不用記住是誰剛剛發了HTTP請求, 每個請求對我來說都是全新的。這一次請求和上一次請求是沒有任何關係的,互不認識的,沒有關聯的。這種無狀態的的好處是快速。
但是隨着交互式Web應用的興起,像在線購物網站,需要登錄的網站等等,馬上就面臨一個問題,那就是要管理會話,必須記住哪些人登錄系統, 哪些人往自己的購物車中放商品, 也就是說我必須把每個人區分開,這就是一個不小的挑戰,因爲HTTP請求是無狀態的。
所以想出的辦法就是給大家發一個會話標識(session id), 說白了就是一個隨機的字串,每個人收到的都不一樣, 每次大家向我發起HTTP請求的時候,把這個字符串給一併捎過來,這樣就能區分開誰是誰了

使用session存在的問題

這樣大家很嗨皮了,可是服務器就不嗨皮了,每個人只需要保存自己的session id,而服務器要保存所有人的session id ! 如果訪問服務器多了, 就得由成千上萬,甚至幾十萬個。
這對服務器說是一個巨大的開銷 , 嚴重的限制了服務器擴展能力, 比如說我用兩個機器組成了一個集羣, 小F通過機器A登錄了系統, 那session id會保存在機器A上, 假設小F的下一次請求被轉發到機器B怎麼辦? 機器B可沒有小F的 session id啊。

1、session sticky , 就是讓小F的請求一直粘連在機器A上, 但是這也不管用, 要是機器A掛掉了, 還得轉到機器B去。
2、那隻好做session 的複製了, 把session id 在兩個機器之間搬來搬去, 快累死了。
在這裏插入圖片描述
3、把session id 集中存儲到一個地方, 所有的機器都來訪問這個地方的數據, 這樣一來,就不用複製了, 但是增加了單點失敗的可能性, 要是那個負責session 的機器掛了, 所有人都得重新登錄一遍, 估計得被人罵死。
在這裏插入圖片描述
      
4、嘗試把這個單點的機器也搞出集羣,增加可靠性, 但不管如何, 這小小的session 對我來說是一個沉重的負擔
怎樣解決?
於是有人就一直在思考, 我爲什麼要保存這可惡的session呢, 只讓每個客戶端去保存該多好?

可是如果不保存這些session id , 怎麼驗證客戶端發給我的session id 的確是我生成的呢? 如果不去驗證,我們都不知道他們是不是合法登錄的用戶, 那些不懷好意的傢伙們就可以僞造session id , 爲所欲爲了。

嗯,對了,關鍵點就是驗證 !

比如說, 小F已經登錄了系統, 我給他發一個令牌(token), 裏邊包含了小F的 user id, 下一次小F 再次通過Http 請求訪問我的時候, 把這個token 通過Http header 帶過來不就可以了。

不過這和session id沒有本質區別啊, 任何人都可以可以僞造, 所以我得想點兒辦法, 讓別人僞造不了。

那就對數據做一個簽名吧, 比如說我用HMAC-SHA256 算法,加上一個只有我才知道的密鑰, 對數據做一個簽名, 把這個簽名和數據一起作爲token , 由於密鑰別人不知道, 就無法僞造token了。
在這裏插入圖片描述

這個token 我不保存, 當小F把這個token 給我發過來的時候,我再用同樣的HMAC-SHA256 算法和同樣的密鑰,對數據再計算一次簽名, 和token 中的簽名做個比較, 如果相同, 我就知道小F已經登錄過了,並且可以直接取到小F的user id , 如果不相同, 數據部分肯定被人篡改過, 我就告訴發送者: 對不起,沒有認證。

token和session的區別:

功能是一樣的,都是要與瀏覽器建立連接,獲取與客戶端對應的用戶數據,只不過完成這個功能的實現方式不太一樣。

本質上的區別:

session的使用方式是客戶端cookie裏存id,服務端session存用戶數據,客戶端訪問服務端的時候,根據id找用戶數據。
token的使用方式是客戶端裏存id(也就是token)、用戶信息、密文,服務端什麼也不存,服務端只有一段加密代碼,用來判斷當前加密後的密文是否和客戶端傳遞過來的密文一致,如果不一致,就是客戶端的用戶數據被篡改了,如果一致,就代表客戶端的用戶數據正常且正確。

流程:

session:

Created with Raphaël 2.2.0註冊登錄服務端將user存入session客戶端將sessionid存入瀏覽器的cookie再次訪問時根據cookie裏的sessionid找到session裏的user

token:

Created with Raphaël 2.2.0註冊登錄服務端將生成一個token,並將token與user加密生成一個密文將token+user+密文數據 返回給瀏覽器再次訪問時傳遞token+user+密文數據後臺會再次使用token+user生成新密文,與傳遞過來的密文比較,一致則正確

注:上文中得token裏保存的用戶信息,一般不會包含敏感信息。

cookie的其他應用場景:

cookie的其他應用場景
http協議無狀態中的 “狀態” 到底指的是什麼?!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章