0%

Session & Cookie

Http 是沒有狀態的,所以每個Request都是不相關的。

Session 是一種讓 Request 變成有狀態的機制,讓瀏覽器和伺服器能互相關聯。而常見實作 Session的一種方法就是 Cookie。

Session & Cookie

Session

Session 是一個暫存的檔案,通常是用來儲存暫時性的資料,比如說使用者的登入狀態,因為 Http 是沒有狀態性的,對於每個 Request 都視是為新的,所以可以透過 Session 紀錄來比對發送 Request 的是誰

流程 :

  1. 瀏覽器傳送了一個 Request 到 Server
  2. Server 將 Request 所提供的資訊(網址所夾帶的參數、Session Id)儲存到 Server 端的暫存檔

實作Session的方法

實作 Session 有兩種常見的方式,分別為 Cookie 和 URL。

Cookie 是實作 Session 的一種方式,用來儲存少量的特定資料,資料不存在 Server 端的暫存檔,而是放在 Cookie 裡面並存在用戶端的瀏覽器,當瀏覽器和 Server 互動時會隨著 Request 和 Response 來回傳送

通常 Session 都會搭配 Cookie 使用來更方便的紀錄資訊。如果只選用其中一個就會有一些問題,例如 :

  • 只用 Session : 只會在用戶端儲存一個 Session Id,當用戶關閉了瀏覽器(分頁)時,Session Id 就會不見
  • 只用 Cookie : 所有資訊都會存在用戶端,一旦資料量大時用戶端可能沒有這麼多空間可以儲存,另外若是用戶端電腦遭到駭客竊取,所有的資料都會曝光

流程 :

  1. Server 收到 Request 後會要求瀏覽器設定一個 Cookie,而這個 Cookie 會儲存一些 Server 要求紀錄的資料,例如 : 一組識別碼用來識別用戶, SessionId, 網址中所夾帶的參數,等等。

  2. 下次瀏覽器要再發送 Request 給這個 Server 時,便會帶著 Cookie 發送給 Server,Server 就可以根據 Cookie 的內容來決定狀態

2. URL

Server 根據 Request 內的參數將用戶導向到新的網址,現今考量網路安全大多不用此方法

以下由購物網站作為範例

流程 :

  1. Server 收到一個 Request 之後,將其所提供的參數擷取出來

market.com.tw?tmp=apple

  1. Server 將提供的參數放進新的網址中

market.com.tw?item1=apple
apple 被擷取出來放進新的網址中

  1. Server 將用戶導向新的網址中

  2. 瀏覽器再次發送 Request 時便會多了新的參數,Server 便可以再需要這些資訊的時候從網址中取得

market.com.tw?item1=apple&tmp=orange
瀏覽器加入了新的參數 tmp

market.com.tw?item1=apple&item2=orange
orange 被擷取出來放進新的網址中

market.com.tw?item1=apple&item2=orange&submit=true
瀏覽器加入了新的參數 submit,代表 Server 可以去處理這些資料了,此時網址裡就有紀錄了 item1, item2

將 Session 儲存到資料庫

Session 是一個暫存檔,而這個暫存檔會造成以下幾個問題 :

  • 大部分大流量的網站會部署在多台主機上,若是只暫存在某台主機上,下次用戶被導向到其他台主機會找不到之前的 Session 暫存檔
  • 若每次 Request 都存到 Server 暫存檔會造成 Server 負擔太大

因此可以將 Session 所需要紀錄的資料存到資料庫便可以解決上述問題。

然而每次都要進資料庫讀取也會有速度上的問題,於是便衍生出了記憶體內的資料庫來提升效能,最常見的是 Redis。想進一步了解什麼是 Redis 以及 Redis 的運作方式請參考本站的 Redis 系列文章

兩種常見的登入驗證方式

這是一種很常見的驗證方式,利用 Cookie 傳送 Session Id,但是若 Cookie 在途中被攔截,用戶很容易遭受到偽造的 Request 攻擊

流程 :

  1. 瀏覽器發送帳號密碼到 Server
  2. Server 驗證帳號密碼成功後便產生一組Session Id放在資料庫
  3. Server 將 Session Id 放入 Cookie 後回傳給瀏覽器
  4. 下次進入網站時,Request 中 Cookie 的Session Id 會一併傳給 Server,若是 Session Id 有效(包含時效),則會繼續處理這個 Request
  5. 當用戶登出時需將資料庫和 Cookie 內的 Session Id 清除

Token-based Authentication

類似於 Cookie-based 的流程,但是 Server 會在 Response 時回傳一組加密的Token,以提高安全性。加密的 Token 可以參考 Json Web Token的介紹。

流程 :

  1. 瀏覽器發送帳號密碼到 Server
  2. Server 驗證帳號密碼成功後便產生一組加密 Token 放在資料庫
  3. Server 將 Token 放入 Cookie 後回傳給瀏覽器
  4. 下次進入網站時,Request 中 Cookie 的 Token 會一併傳給 Server,Server 會將 Token 解開做驗證,若驗證成功則繼續處理 Request

參考

[1] 白話 Session 與 Cookie:從經營雜貨店開始
[2] How To Work With Session And Cookies In CodeIgniter
[3] session、cookie and token | iT邦幫忙