前幾天在介紹 JWT 時,有提到跟 Session 相比 JWT 不用存在 DB 或 server,那 Session 的作用是什麼?
跟 JWT 相比什麼時候適合用 Session? 今天我們就來探討一下,它的運用~
從翻譯來看 Session 可以是會話或會議,顧名思義,需要兩個人以上彼此交流,才能成為一個 Session,因此它會有開始和結束,我們可以把它當作是一段時間內所發生的狀態,其中有開始和結束。
在 HTTP 之中,他指的是儲存在伺服器端的使用者狀態,用途和 JWT 一樣,它可以用來記錄登入的狀態,讓使用者登入後,瀏覽其他網頁不會需要再登入一次。
常見的例子像是 ChatGPT 登入一段時間後,可能就會跳出登入階段已過期,要你重新登入,這就是一段 Session 的結束。
Session 的機制會在使用者首次登入時,伺服器會為該使用者創建一個 Session,裡面儲存使用者的資料,並將這些資料存在 DB 或 memory,使用者之後瀏覽其他網頁時便會在 url 帶上 Session id,伺服器可以透過 Session id 來辨識使用者。
但這樣做等於把 session_id 給公開,且所有資訊都存在 server 端,會增加存放的成本,若今天是大型伺服器,經過負載平衡也不能確定 Session 是存在連到的那台的 DB,因此而衍生出了 Cookie。
Session 的機制會與 Cookie 配合使用。當使用者首次登入時,伺服器會為該使用者創建一個 Session,裡面儲存使用者的資料,並回傳一個儲存在 Cookie 的 Session UUID 給瀏覽器,使用者之後瀏覽其他網頁時,伺服器就會透過 Cookie 的 Session id 來辨識使用者。
Cookeie 可以隨著 HTTP request 一起發送到伺服器,因此也減少了暴露 Session id 的風險。
Session 也能透過存在 Cache 如: Redis,讓多 server 可以拿到 Session。
一塊小餅乾,是一段由Server送給使用者瀏覽器的一小塊資料(文檔)。
瀏覽器會儲存它並且在瀏覽器下一次發送要求的時候將它送回原本送來的伺服器。
過小的資料儲存量和安全性的,在搭配 Session 使用後,都會有效的緩解這些問題,但你可能會想配合 Session 就一定不會有安全性問題嗎? 這沒有 100 % 保證,因為可以透過竄改 Cookie 裡的 Session id,多次嘗試訪問其他用戶的 Session 信息,如果伺服器對 Session ID 的驗證不夠嚴格,竄改的 Cookie 就可能訪問到 Session id,導致未經授權的訪問。
這時候就出現可以防竄改的 SignedCookie。
Signed Cookie 是一種加強版的 Cookie,它在標準 Cookie 的基礎上,加入了簽名機制,以提高安全性和防篡改能力。
其實運作方式也很簡單,就是伺服器將 Cookie 資訊回傳給瀏覽器時,在其中加入一段 secret ,並用 hash 加密,這樣攻擊者在竄改時就不知道 secret 是什麼,傳回來時也註定會錯誤。
有人可能看過一些言論表示 JWT 比 Session 好用,但實際上還是要看時機來使用才是最好的:
e.g. :
這是一些例子,但實際上還需要看系統架構、使用場景和不同的需求應對,甚至也有兩者並用的情況。