深入理解cookie和session,這一篇就夠了(建議收藏)

2020-10-06 14:00:40

導語:
在web開發中,總是有看到cookie還有session這兩個東西,那麼它們到底有什麼用,這一篇詳細告訴你。

因為http協定是無狀態的,每次的請求存取都是獨立的,沒辦法追蹤到上一次存取的狀態,後端就無法知道這次的存取是哪位,所以就要一些技術來幫助後臺辨別這次的請求是誰。而這兩者Cookie與Session都是Web程式中常用的技術,用來跟蹤使用者的整個對談。

  1. Cookie通過在使用者端記錄資訊確定使用者身份,(相當於你有一張身份證,跟後端交流前要拿出身份證給後端看一看,然後後端才能確認你的身份。
  2. Session通過在伺服器端記錄資訊確定使用者身份。(你不用身份證,你只要說出自己的名字,然後後端在它們使用者簿上找一找有沒有你的名字,最終確認你的身份。

瞭解了它們的大概後,我們現在深入瞭解它們吧。以及瞭解什麼情況使用session或者cookie。

一,session

1,session簡介

Session是伺服器端使用的一種記錄使用者端狀態的方法,雖然簡單而且安全一些,但是會把使用者資訊存放在後端的記憶體中,導致記憶體變大,可能會導致溢位(後文會講到解決方法)。

2,session是怎麼執行的

當你開始跟後端聯絡的時候,後端就會根據你的情況給你分配一個sessionid(唯一),這個sessionid就會存放在cookie中,而且cookie中只需要存放這個資訊就行了,後端設定這個sessionid存在的最長時間,時間到了自然這個sessionid就消失了,同時後端中的相應記憶體也會釋放。

有了這個sessionid後,每次跟後臺交流,都會拿著這個id去校驗一下,確保後端明白你的身份,身份確認後,就可以開始交流了。

3,session實現登陸

const session = require('koa-generic-session')

app.keys = ['xiaomizhou123_']
app.use(session({
  //設定cookie
  cookie: {
    path: '/',
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000			//存在的最長時間
  },
  //設定redis
  store: redisStore({
    all: '127.0.0.1:6379'    //寫死本地redis
  })
}))
//登陸後session中就會有你的資訊,每次跟後端的交流前都要驗證你的身份,並且更新最後交流時間,只有當session過期了,你跟後端的對談才要重新登陸。

4,Session的生命週期

Session儲存在伺服器端。為了獲得更高的存取速度,伺服器一般把Session放在記憶體裡。每個使用者都會有一個獨立的Session。如果Session內容過於複雜,當大量客戶存取伺服器時可能會導致記憶體溢位。因此,Session裡的資訊應該儘量精簡。

Session在使用者第一次存取伺服器的時候自動建立。

Session生成後,只要使用者繼續存取,伺服器就會更新Session的最後存取時間,並維護該Session。使用者每存取伺服器一次,無論是否讀寫Session,伺服器都認為該使用者的Session「活躍(active)」了一次。

5,Session常用方法

  1. secret:一個String型別的字串,作為伺服器端生成session的簽名。
  2. name:返回使用者端的key的名稱,預設為connect.sid,也可以自己設定。
  3. resave:(是否允許)當用戶端並行傳送多個請求時,其中一個請求在另一個請求結束時對session進行修改覆蓋並儲存。 預設為true。但是(後續版本)有可能預設失效,所以最好手動新增。
  4. saveUninitialized:初始化session時是否儲存到儲存。預設為true,但是(後續版本)有可能預設失效,所以最好手動新增。
  5. cookie:設定返回到前端key的屬性,預設值為{ path: '/', httpOnly: true, secure: false,maxAge: null }
  6. Session.destroy():刪除session,當檢測到使用者端關閉時呼叫。
  7. Session.reload():當session有修改時,重新整理session。
  8. Session.regenerate():將已有session初始化。
  9. Session.save():儲存session。

6,如何解決session存放在後端,記憶體溢位,或者後臺多程序間記憶體不共用問題。

可以使用redis,重新開一個程序,將伺服器上的幾個後臺程序的session資訊存放在redis中,既可以解決記憶體溢位的問題,又可以解決進場間通訊的問題,但是有可能會引發redis的其他問題,這又是另外的一個知識點了,不在本文的討論範圍。但是合理的後臺編寫,是可以解決這個問題的。

二,cookie

1,Cookie簡介

使用者端請求伺服器,如果伺服器需要記錄該使用者狀態,就向用戶端瀏覽器頒發一個Cookie。使用者端瀏覽器會把Cookie儲存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給伺服器。伺服器檢查該Cookie,以此來辨認使用者狀態。伺服器還可以根據需要修改Cookie的內容。(也就是給你一個身份證,上面記錄了你的資訊,每次跟後臺的交流前,後臺都要看看你的身份證過期了沒,然後才跟你通話。

2,Cookie的不可跨域名性

既然這些資訊都是存放在我們的使用者端(瀏覽器)上,那麼瀏覽器上面存放了這麼多的cookie,就不會混亂嗎,比如我存取qq的網址,拿了阿里的cookie(身份證),就過去了?

答案是不會的,瀏覽器的合格與否,就是要看看它的cookie是否會存放和使用好。跨域的cookie是不能夠共用的。

3,cookie安全性

既然是存放在使用者端上,那麼就會存在被修改的危險,如果這個cookie是明文存放的,那麼我相信小白也能夠隨意更改資訊(相當於你把你的身份證改成了別人的名字,然後就冒充那個人去跟後臺交流)。

早期的cookie確實存在這樣的問題,但是肯定要進步,就給加密起來了,現在你的cookie上面都是亂碼,只有後臺程式才知道這個亂碼要怎麼解密,變成你的身份,我們亂修改就會導致你的身份證失效。

4,cookie的效率

由於每次跟後臺存取的時候,都要攜帶上這個cookie,我們坐一個假設,如果我們的cookie是5kb,然後我開啟csdn的首頁,它上面是首頁要請求的次數是200多次,那麼在開啟首頁的過程中,就要消耗5kb×200多=1mb多的流量。

拜託,我們才只是開啟一個頁面而已,光是身份證驗證就已經消耗了1MB的流量了,而且還沒算上200多次請求返回來的資料流量,算上圖片,文字啥的,你開啟一次首頁就要消耗幾MB。

所以我們要將cookie的大小壓縮一下,不必要的就不放進去了,太浪費流量和效率了。

補充
在這裡插入圖片描述
微信搜尋【web小館】,回覆全棧部落格專案,即可獲取專案原始碼和後續的實戰文章教學。每天用最簡單樸實的語言,潛移默化的提升你的計算機基礎知識和前端技術。小米粥,一個專注的web全棧工程師,我們下期再見!

在這裡插入圖片描述
node後臺