進度條

[不是工程師] 會員系統用Session還是Cookie? 你知道其實他們常常混在一起嗎?

「帥哥~你的早餐好了」,五分鐘概述網路界的記憶大神-Session

作者: Vincent Ke 更新日期:

上一篇文章我們提到,在網路發展便捷的背後裡,我們有一個看不見的工臣「小餅乾 Cookie」(一般溝通請不要使用小餅乾indecision)。

 

「不是工程師」系列是以生活化 / 口語化的方式,
提供科技用詞或是功能另外一種理解的方式,
所以很多用詞與邏輯可能不是那麼的嚴謹,還請見諒。

 

舉凡像是登入來說,過去我們總是必須藉著不斷又不斷的登打帳號密碼,來完成網站上身分驗證的這件事情,起因當然是因為HTTP的無狀態(stateless)通訊協議造成的,而Cookie就是用來繞開HTTP的無狀態性的「額外手段」之一,讓伺服器可以設定或讀取Cookies中所包含資訊,藉此來維護我們在使用服務時,可以在背景完成向伺服器發送請求,接著伺服器就匯回傳包含登入憑據(使用者名稱加密碼的某種加密形式)的Cookie文檔,到使用者的硬碟(或記憶體上),在之後登入時,只要Cookie尚未到期,瀏覽器會傳送該Cookie給伺服器作驗證憑據,來減少重複登入的輸入行為。

 

內置圖片 2

 

就像我們點餐之後,店員會給我們一張點餐明細與號碼,當他叫號的時候會再跟你作確認,或直接以明細上的內容取餐。

 

也許這樣的方式就已經可以解決大多數的問題了,但想必大家一定有經驗,在公司或是住家附近的早餐店,總是有那種記憶力神強的老闆娘,不只可以在你喊出號碼時碼上反應出你點了什麼,還可以依據你的臉蛋特徵來記憶你對餐點的喜好,甚至還會再點餐之於跟你閒話家常一下

 

「欸帥哥是不是又瘦了,欸帥哥剪頭髮喔,帥哥今天奶茶是不是一樣奶要多一點?」,這樣的互動不僅溫馨,還可以增加顧客對店家的品牌忠誠,例如忘記帶錢的時候,老闆娘還會看你常買加上長的帥特別讓你奢帳一次。但我們不能強求每一間店家都可以作到這種神強的記憶能力,對吧。這一點在網路通訊的世界上其實也是同理可得的。

 

內置圖片 4

 

這裡我們必須再提及一次HTTP的特性了,我們想像一下他就是一個完全不記臉的大賣場臭臉老闆娘,因為HTTP 本身是無狀態(Stateless)的協議,無論是客戶端還是服務器端,每一次的請求都是獨立性質,而且沒有必要紀錄彼此過去的互動行為,自然而然他沒辦法記憶你每次請求的內容,儘管在上一個章節我們提到可以使用Cookie,也就是把資訊記錄在本機端的文檔這樣的機制,讓瀏覽器可以透過一些原則把資訊送給伺服器,來達成讓「客戶端」自動與「伺服器端」保持聯繫和溝通的狀態,但記得,Cookie就像那張取餐的號碼牌,認號不認人,如果今天遺失或是被別人幹走,那你的餐點就會被其他人給領走,更別提關閉瀏覽器之後Cookie就會有被清除的風險了。

 

 

那Session又是什麼呢?

 

 

Session有點類似會話的概念,可以泛指有始有終的系列動作/消息,比如從播打電話到交談、掛斷,這樣的一個會話期間,可以稱之為Session,所以中文翻成會期似乎也不為過。

 

而Session機制是一種服務器端的機制,服務器使用一種類似於散列表的結構(也可能就是使用散列表)來保存信息。從網路通訊協議角度來解釋時,它表示了「面向、連接」和/或「保持狀態」這樣兩個異議, 「面向、連接」表是客戶端和Server端通信前要先建立一個通信的渠道,比如電話,當然是指對方接了電話,開始交談後通信才開始,若只是寫寫信或是傳訊息,你把資訊發出之後並不能確認這樣的通信渠道有成功被建立,例如連已讀都沒有,接收方當然沒有開始通訊,但對發信人來說,通話已經開始了

 

內置圖片 5

 

 

而另外一個「保持狀態」,則是指通信交談的其中一方,可以所有的消息作關聯,使得消息之間可互相連結,並且依賴,就像是巷口的早餐店阿姨,還記得你最愛吃的火腿蛋不喜歡有美乃滋。而Session則是一種持久網路協定,讓Client端與Server端可以作一種對話,並將兩端建立關連,保持伺服器與Client可以持續的與Server作交談。

 

 

所以我們可以想像Cookie是一張領餐的號碼牌,而Session可以是一張數位會員卡,不僅可以記錄你的點餐號碼,還可以記憶你的餐點細節,消費記錄和點餐喜好...等。而這就解決號碼牌遺失領不到餐的問題,但是他不是記憶你帥氣得穿搭或長像,而是靠著所謂的Session ID。

 

當我們需要為某個客戶端的請求創建一個Session的時候,服務器首先檢查這個客戶端的請求裡是否有包含了Session標識,就是剛剛提到的 Session id,當然如果已包含一個Session id,就表示這個客戶是老司機啦,當然伺服器端以前就為了這個客戶端創建過Session,服務器就按照Session id,把這個Session找出來使用。但如果客戶端請求不包含Session id,,則表示他是新臉孔,那伺服器端就為此客戶端創建一個Session,並生成一個Session id,並在本次響應中返回給客戶端保存。

 

但是在最初的 Session 設計中,我們都會把資料記錄在 Server端 上,如 Database、記憶體或是利用檔案交換的方式,來把你的點餐資訊作儲存,而當你去領飲料時,店員會輸入你的號碼,並在叫出你點的內容。但如果是大型網站上,如果有負載平衡的機制,你怎麼能確定你當初輸入和最後取餐的Server是同一台呢,而這樣作當你資料量大時,也會有效能影響的問題,這時候Cookie就出場了。

 

內置圖片 8

 

保存這個Session id的方式也可以採用Cookie,但似乎很多人都有一種彷彿瀏覽器關掉Session也會消失的錯覺,但本質上並非如此,就像會員卡,除非你主動提出銷卡,否則店家不會刪除顧客資料,這件事情對Session來說也如出一轍,除非通知Server刪除Session,否則Server端會一直保留來保持會話暢通,但瀏覽器從來不會主動在關閉前通知服務器要關閉,大部分Session機制都使用會話Cookie來保存Session ID,而關閉瀏覽器後因為Cookie消失造成 Session id也消失了,但只要把原來的Session ID再發送給Server,那還是能夠找到原來的Session 。

  

但大家都會擔心,Cookie和Session得結合,到底還會不會有被竄改的問題,這個時候就要靠"簽章"來驗證資料的真實性,在我使用Cookie請求時,可以加一個簽章,也就是在我傳輸的資料後面加上一個對應的秘密字串,當伺服器回傳時,可以回應該字串,若是其他使用者偷偷串改的話,由於串改的資料和我的秘密字串無法相符,當然也無法作偽造,這就是所謂的 SignedCookie,但記住Session就像是你的臉,也是你的會員卡號,不見也表示仍然有資料被竊取的風險。

 

內置圖片 7

 

總之Session是一種靈活且機動的應用,有鑒於使用再Cookie上仍有一定的資料風險,而透過SignedCookie也有造成資料傳輸量變大的問題,我們會再接續的文章中介紹Session的後續應用,請拭目以待。

 

校正小編補充:

如果單就實現功能,Cookie與Session彼此之間是可以互換的(指的是你可以把資料存放在Session或是Cookie,並不是指Session可以被放在Client端當Cookie使用)。但是Cookie在最單純的情況裡,是有安全性的問題(資料在Client端)。所以考量到這點,大部分都會選擇Session。但是正如Cookie是一個外加的功能,Session也不屬於HTTP協定。只要是外加功能,就必須額外寫程式實現。


不過現在做網站我們都流行使用框架,Session的機制都被框架所實現了,以Ruby on Rails來說,預設的Session實現方式是由Cookie來實作的(利用加密與設定過期時間)。每個框架實現的邏輯都可能不一樣,所以還是要去看官方的說明會比較清楚。但從這裡可得知,Session並不是一個很明確實體的機制,算是一個概念,只要符合概念所實作出來的功能都可以被叫做Session。


補充:Ruby on rails Session::CookieStore

 


最後,如果你喜歡我們的文章,別忘了到我們的FB粉絲團按讚喔!!

Medium vincent

Vincent Ke

喜歡把混亂的事情變的簡單 用嘴巴做事其實很可以 但要結合靈活的腦袋思考 就一起來拆解吧