iT邦幫忙

2021 iThome 鐵人賽

DAY 25
0
Software Development

PHP 語法通關系列 第 25

Day25 來人上菜! 給我來點Cookie and Session

前言:

一直以來都知道網頁有Cookie,甚至有時候網頁跑不出來的時候很多人的建議都是清除Cookie,但直到我需要用到前,都沒有好好了解過到底Cookie指的是什麼,同時也延伸了何謂Session,今天我們就要來了解兩者以及差別!!

HTTP

HTTP 是一個無狀態**(stateless)**的通訊協定,可以在Client與Server兩端進行溝通,但無法紀錄網路上的行為,伺服器並不會記住使用者是誰,而是每一次收到的請求視為獨立的行為。

如果是純粹展示靜態內容的網站,無狀態不會是問題,HTTP是很棒的優點,因為client客戶端、server伺服器、database資料庫都不需要儲存使用者的狀態、資料,省去了大量的儲存空間;但在複雜的網路應用、動態網頁時,比如要登入一個網站或是網頁上填資料時,每次訪問該網站,就需要將再輸入一次(因為每次請求都不會留下資料),需要辨別使用者身分時,無狀態的通訊就會是個問題。

那該怎麼解決 HTTP 無紀錄狀態的問題,該怎麼做呢?

Session 和 Cookie 的主要目的就是為了彌補 HTTP 的無狀態特性。

Cookie

Cookie(小餅乾或稱小型文字檔案) 就是用來解決HTTP的無狀態特性的手段之一,是一段由伺服器送給使用者瀏覽器的一小塊資料(文檔)。

Cookie 應用例如:在資料填寫上,有時候手滑跑出去,但再回來頁面的時候發現剛剛填的資訊都還在,這其中靠的就是 cookie, 伺服器可以設定或讀取Cookies中所包含資訊,只要Cookie尚未到期,瀏覽器會傳送該Cookie給伺服器作驗證憑據,來避免HTTP無狀態性的問題。

Cookie設定值是儲存在使用者的電腦裡,可透過瀏覽器來檢測這個設定值是否儲存,開啟瀏覽器,輸入要查看網址點選左上角的小圖示

client 端的程式在一旦填寫的資料有變動時,就把該資訊寫入 Cookie。

Cookie 雖然好用,但有弊端,Cookie 中的所有數據在Client端就可以被修改,數據非常容易被偽造,那麼一些重要的數據就不能存放在cookie 中了,或是數據太多反而影響傳輸效率等,為了解決這些問題,session就誕生了! session 中的數據是保留在Server端。

Session

#RFC 2109
This document describes a way to create stateful sessions with HTTP requests and responses. Currently, HTTP servers respond to each client request without relating that request to previous or subsequent requests; the technique allows clients and servers that wish to exchange state information to place HTTP requests and responses within a larger context, which we term a "session".

Session定義,真的難懂,不過簡單來說,Session 所代表的是「狀態」,如果沒有了狀態,一大堆功能都會失效。

Session負責紀錄在 Server端上的使用者訊息,會在一個用戶完成身分認證後,存下所需的用戶資料,接著產生一組對應的 ID(Session ID),存入 Cookie 後傳回用戶端。

所以我們可以想像Cookie是一張領據,而Session是一張會員卡,上面記錄了一些資料,當我們提出請求Request,伺服器端Server(老闆)會根據你專屬的Session ID,回應給你需要的東西,但如果你是新會員沒有紀錄(客戶端請求不包含Session id),則表示你是新臉孔,那Server就為此客戶端創建一個Session,並生成一個Session id,並返回給客戶端保存。

可以採用Cookie保存這個Session id,很多人都有一種彷彿瀏覽器關掉Session也會消失的錯覺,實際上關閉瀏覽器不會導致Session被刪除,像銀行卡,除非你主動提出銷卡,否則不會刪除資料,通常Server為Seesion設置了一個失效時間(默認30分鐘)保存這個Session,過了時間就會銷毀這個Session,但程式設計師通常會保存起來,好處是沒了時間的限制,壞處是隨著時間的增加,這個資料庫會急速膨脹,特別是訪問量增加的時候,因此當服務器認為Client客戶端已經停止了活動,會把session刪除以節省存儲空間,以減輕伺服器壓力。

  • 不過不知道有沒有讀者想到一個問題,那就是Cookie和Session有沒有被竄改的問題?

Cookie 被拿來解密竄改,假設今天我是一般會員“Winnie”,我把自己改成VIP會員“Ritabear”,偽裝成另外一個身分,那我能用的權限就高了,這個時候就要靠SignedCooke 簽章驗證資料的真實性,使用Cookie時,可以加一個簽章,也就是在我傳輸的資料後面加上一個對應的秘密字串,當伺服器回傳時,可以回應該字串,讓我們的Cookie不容易被竄改,由於串改的資料和我的秘密字串無法相符,當然也無法作偽造,這就是所謂的 SignedCookie。

  • 總結:

    引入 Cookie 與 Set-Cookie 兩個 Header 來建立 Session。

    伺服器透過 Header 的屬性 Set-Cookie,把使用者的狀態紀錄儲存在使用者電腦裡的 Cookie,而瀏覽器在每一次發送Request時,都在 Header 中設定 Cookie 屬性,把 Cookie 帶上,伺服器就能藉由檢視 Cookie 的內容,得知瀏覽器使用者的狀態;而像是「從登入到登出」、「從開始瀏覽網頁到 Cookie 失效」,或是任何伺服器能認出使用者狀態的時間區間,就叫做 Session

    建立 Session 之後,所儲存的狀態就叫做 Session information,若是選擇把這些資訊存在 Cookie 裡面,就叫做 Cookie-based session;還有另一種方法則是在 Cookie 裡面只存一個 SessionID,其他的 Session 資訊都存在 Server 端,靠著這個 ID 把兩者關聯起來。

Cookie Session
基本定義 小文件,記錄一些對網站的個人設定 狀態
資料儲存 存放在Client端(不會造成伺服器端的過載) 儲存在Server端
提醒 SessionID寫在裡面 一個SessionID對應一筆SessionID
失效 存在用戶端的cookie,不會因為瀏覽器的關閉消失(直到時效失效為止) Session 在伺服器端並不會自動失效,除非session已經超過設置的失效時間。
風險 Cookie傳送時是以明碼方式傳送,機密資料不建議以此方式儲存

PS. expires是過期的意思,所以這是個一天之後就會過期的Cookie。如果不設定的話,在關掉瀏覽器的時候Cookie就會被清除。

伺服器把狀態放在 Set-Cookie 這個 Header 裡面送去瀏覽器,而瀏覽器在之後的 Request 把 Cookie 帶上去,這樣子就成立一個 Session 了,因為後續的 Request 就有了狀態。


上一篇
Day24 類別與物件--魔術方法3、trait
下一篇
Day26 Cookie 的使用-1
系列文
PHP 語法通關30

尚未有邦友留言

立即登入留言