[Web] Cookie & Session 介紹

Andy Chou
7 min readJul 1, 2019

--

前言

在介紹Cookie和Session之前,總是要先了解為何會需要Cookie和Session ?

那是因為http是個無狀態( Stateless)的協議,也就是每個 request 是毫無關連性的,不會紀錄下任何的資訊。由於http的無狀態,造成今天如果要登入一個網站,每次都需要將帳密重新輸入一次, 或是現在頁面上的表單填到一半,不小心把網頁關掉,只好再重新輸入一次表單,使用起來會非常不便。

因此,產生了Cookie和Session來解決http無狀態的問題。

Cookie

什麼是cookie?

大多數的網站在你瀏覽後,會在你的電腦記憶體 or 硬碟中留下一些小小的純文字檔案,就是所謂的 Cookie。

$ locate Cookies
....
/home/username/.config/google-chrome/Default/Cookies
....

當你再去瀏覽這些網站時,系統便會去讀取這些 Cookie 檔並且會重新儲存一遍。 透過上述的方式就能夠紀錄上一個request的資訊。而不同的瀏覽器有不同管理 cookie 資料的方法,以 Chrome 為例,他使用 Sqlite (i.e 一個小型的資料庫) 來管理 cookie。

Chrome 瀏覽器的Cookies 資料可以發現它很像是一個 table

cookie存在的用途及運作方式?

如同前言所述,在網路世界中,client 與 server 間的溝通需透過 HTTP 協定發送 request 和接收 response,但由於 HTTP stateless 的設計,requests 之間是獨立的個體,也就是說 server 端無法記住 client 端發送過哪些請求以此來記住 client 目前的狀態。

為了讓 server 端能記住 client 的狀態,HTTP 利用 Cookie 和 Set-Cookie 這兩個 header 提供 cookies 的功能,以下是 HTTP cookies 的運作方式:

Step1. Client 發送帶有其資料的 request。

Step2. Server 會使用 Set-Cookie header 告訴 browser 這些資料要存在 Cookies 資料庫,當 Chrome 收到帶有 Set-Cookie 的 response 時,會將 Set-Cookie 的 value 存入 Cookies 資料庫 (ex: Crome SQLite database)。

Step3. 接著當Client 透過 Chrome 發送請求到 “test.com” 這個 domain 時,Chrome 會從 Cookies 資料庫中讀取所有關於 “test.com” 這個 domain 的 Cookies 資料,並放在 request 的 Cookie header 中。

Step4. 最後 Server 透過解析 request Cookie header 中的資訊,了解 client 目前的狀態。

cookie與同源政策?

在上述的例子我們可以發現 Chrome 在讀取 Cookie 資料時會根據 request 的目前的 domain name 來找對應的 Cookie 資料,這項行為是受限於-同源政策。

同源政策是用來限制網路資源共享的規則,當網路資源有著相同的 1. 協議 2. 網域 3. 端口 時,這些資源才可以彼此共享。

在testA.com網域的cookie資料就不會傳給testB.com

Cookie的資料屬性?

1. 存在Client端(瀏覽器),安全性較低,但可以加密後存放。

2. 只存在原本的Domain底下。

3. 以key/value方式儲存,儲存時間可以根據需要進行設定:

  • 如果沒有設定Cookie失效日期,它的生命週期儲存到關閉瀏覽器
  • 若Cookie物件的Expires屬性設定為MinValue,表示永不過期

4. Cookie的資料大小單位是bytes,一個 Cookie最大可以是 4096 bytes,而一個 domain 最多只能有 20 cookies。

5. 由於每次 request 必須將 cookies 的資料放在 headers,所以當 cookies 的資料變大時,request 也會變大,過大的 request 會影響網路傳輸的速度。

Session

Session的發展起因?

Cookies 和 Session 存在的目的都是幫助 Server 記住 Client 的狀態,差別在 Cookies 是將狀態資料存在 Client 端(ex: Browser),而 Session 則是將資料存在 Server 端 (ex: Redis)。

那麼問題來了,這兩個相似的技術有什麼關係呢?其實 Session 並不是用來替代 Cookies ,而是用來彌補 Cookies 的不足

Session存在的用途及運作方式?

為了彌補 Cookies 的不足,我們會在 Server 端使用 Session 的機制去儲存這些狀態資訊,並產生一組 Session key 放入 Cookie 中,由於狀態資訊是直接存在 Server 端的,所以使用者無法讀取,使用者只能看到 session key 但不知道其結構,同時也能避免 Cookie 存入過多資料。

Session-based authentication 是 stateful 的驗證機制,也就是 Server 端和 Client 端都必須儲存狀態資訊,例如 Server 端必須將使用者資料存在 Session database,而Client 端也必須用 Cookie 儲存 session_id。

Step1. Client 發送帶有其資料的 request。

Step2. Server 端的 Session database(ex: mysql or redis)會將使用者資料存起來,並產生一組session _id,透過Set-Cookie header傳給Client端。

Step3. 接著當Client 透過 Chrome 發送請求到 “test.com” 這個 domain 時,Chrome 會從 Cookies 資料庫中讀取所有關於 “test.com” 這個 domain 的 Cookies 資料,並將session_id放在 request 的 Cookie header 中。

Step4. 最後 Server 可以拿到request Cookie header 中的session_id資訊,去session database查找使用者資訊。

Session 限制?

不適用於API-Based 的架構上。

原因是 session_id 必須儲存於 cookie 中,而 cookie 必須遵守同源政策, 也就是說如果Web Server 和 API Server 的 domain 不同,Web Server 無法將 session_id 透過 cookie 傳送給 API server,因此 API Server 也無法驗證使用者的身分。

解決方式?

可以採用Token來解決上述的問題。

--

--

No responses yet