# Cookie & Session - 筆記 ###### tags: `HTTP` `cookie` `session` `authentication` `web security` :::warning :bulb: 本站筆記已同步更新到我的[個人網站](https://simplydevs.netlify.app/)囉! 歡迎參觀與閱讀,體驗不同的視覺感受! ::: [TOC] ## :memo: HTTP 的無狀態 (Stateless) 特性 HTTP通訊協定(HTTP Protocol)具無狀態(Stateless)的特性,這表示每個伺服器所接收的HTTP request是獨立的,並且與先前接收到的request不相關。伺服器不會保存client的狀態,因此伺服器給予的response是根據當下的狀態。 **無狀態協定具有特性如下:** * 簡化了伺服器的設計 * 因為系統不需要追蹤多個連結通訊與session的細節,因此無狀態協定所需資源較少。 * 在無狀態協定中,各個封包(packet)各自運輸,與其他封包無涉 * 伺服器與客戶端之間的依賴程度低 因此,如果我們希望伺服器能認出 request 的狀態 (例如之前已經登入),我們可以讓 request 本身攜帶充足的資訊,來幫助伺服器判斷這個 request 是否為會員系統裡的某位使用者,再進一步判斷這位使用者的狀態。而所謂「讓 request 本身攜帶充足的資訊」,類似會員卡的概念,我們會**讓 request 攜帶一串憑證,伺服器可以用這串憑證進一步查找資料庫裡的使用者資訊,cookie就是達成這種目的的一種憑證**。 ## :memo: 憑證 ### 用戶端如何保存憑證 保存憑證的方法有很多種,瀏覽器本身提供了 cookie 和 web storage 等機制,如果有特殊目的,也可以拉出去儲成獨立的外部檔案。  <p style="text-align:center">兩種不同的web session管理機制</p> <h6 style="text-align:center;">(Source: Alpha Camp material)</h6> ### 伺服器如何比對 request 攜帶的憑證? 真正的使用者資料存在資料庫裡,所以在應用程式伺服器上也需要建立一個儲存機制,才能把用戶端、應用程式伺服器、資料庫三個地方的資訊匹配起來。 在應用程式伺服器上,用來存放使用者狀態的機制,稱為 session。 ### **Session**  <p style="text-align:center">session與cookie儲存使用者資訊的方式</p> <h6 style="text-align:center">(Source: Alpha Camp material)</h6> Session 翻譯成「會話」,這是抽象的概念,代表 **「用戶端與伺服器之間一系列的交流」**,你可以把一個「登入-登出」的週期視為一次「會話」。 * 通常「伺服器的 session」和「用戶端的 cookie」是相對存在的解決方案。 * session 也是一個 key-value pair 的結構,可以先想像成一個龐大的物件,裡面的資訊都和使用者登入記錄有關 * session通常儲存在: * 記憶體(預設) * 資料庫,如MySQL、MongoDB * cache,如Redis、Memcached * 常見的session攻擊如[session hijacking](https://owasp.org/www-community/attacks/Session_hijacking_attack),攻擊者竊取session ID並送至伺服器,若伺服器未檢查session ID的使用者身分,即可成功獲取該ID使用者的相關資訊。 * 常見預防session攻擊的措施包含: - 增強session ID的長度、隨機性,使攻擊者難以猜測 - 設置session的有效期限(time-out) - 增強cookie的安全性 - 設置HTTPS-Only ### **Cookie** Cookie是使用者瀏覽網站時,由伺服器建立,傳送給瀏覽器,並透過加密的方式儲存在用戶端(Client Side)上的小片段文檔(text)。 * Cookies是key-value pair 的結構,儲存session ID,不儲存session data(session data存在資料庫裡,[如圖所示](###Session)),由HTTP response header設置,有效期為直到瀏覽器關閉或cookie過期: `Set-Cookie: Key=Value` 實際上看起來像是`Set-Cookie: sessionID=91laR31m` * Cookies可能會儲存敏感的個人資訊,例如個人偏好或瀏覽紀錄,所以應該確保cookie的安全性,例如透過 **1. 增加cookie到期時間:** `Set-Cookie: Key=Value; expires=Monday, 13-March-2023 09:20:10 GMT` **2. 增加HttpOnly的特性:** 透過增加[HttpOnly](https://owasp.org/www-community/HttpOnly)的特性,確保cookie的資料不會因XSS攻擊(Cross-Site Scripting)經由JavaScript直接存取session cookie。 `Set-Cookie: Key=Value; expires=Monday, 13-March-2023 09:20:10 GMT; HTTPOnly` **3. 增加其他特性:** [SameSite](https://owasp.org/www-community/SameSite):避免CSRF(Cross-Site Request Forgery)攻擊 [Secure](https://owasp.org/www-community/controls/SecureCookieAttribute):確保只有https的網站可以獲得cookie的資料 更多詳情可參考[MDN文件](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value)關於Set-Cookie的解釋 * 通常儲存Cookie的地方包含:**記憶體或硬體**內,記憶體是由瀏覽器來維護的,通常會在瀏覽器關閉後清除,不同瀏覽器間的Cookie無法相互使用;硬體的Cookie則有保存期限,除非過期或是手動刪除,否則儲存時間會較瀏覽器來的久。 ### **Session-Cookie運作模式** 1. 使用者進入網站,伺服器產生session和session ID 2. 伺服器的response header中可以Set-Cookie,寫入session id及其他屬性,瀏覽器收到response,儲存一個存有session ID的cookie(但不應包含任何私人資訊) 3. 存放有session ID的cookie自動連結在之後的HTTP request,傳送給伺服器 4. 伺服器接收到含有session ID的cookie的request時,解析session ID並回傳該ID相關連的session資料 5. 只要session 處於active狀態,此過程重複且持續進行 6. 當使用者關掉瀏覽器/登出/超過預先設定的session時限(如:30分鐘),session和對應的cookie即過期。 ### **利用Cookie與Session進行使用者認證** <h6 style="text-align:center">(Source: Alpha Camp material)</h6> * 第一次登入:伺服器建立一個 session :arrow_right: 把 session id 交給用戶端:arrow_right:用戶端把 session id 保存到瀏覽器的 cookie 裡。 * 下一次登入:同一個瀏覽器發送請求:arrow_right:附上同一組 session id:arrow_right:伺服器會判斷「這個 request 來自一個登入過的使用者」:arrow_right:這個瀏覽器可以使用授權的服務內容。 * 登出:把這個 session id 消滅掉:arrow_right:結束這一回合的會話 (session)。下次再進入網站時,又需要重新登入、建立新的 session。 ### 使用者認證的安全性 cookie 保存在用戶端,而用戶端可以隨意修改自己的本地資訊。如果認證機制如此單純,使用者就可以修改自己的session id假冒他人登入,因此伺服器當然不可以允許這種事發生,不但資訊本身要加密,session 裡還需要有其他的驗證機制,防止用戶端偷改資訊以及避免資訊外洩。 --- ## 參考資料 * Alpha Camp教案 * [Day25 來人上菜! 給我來點Cookie and Session](https://ithelp.ithome.com.tw/articles/10278733) * [[不是工程師] Cookie 是文檔還是餅乾?簡述HTTP網頁紀錄會員資訊的一大功臣。](https://progressbar.tw/posts/91) * [深入理解無狀態協議、HTTP 與 web 會話](https://blog.csdn.net/antony1776/article/details/83474496) * [白話 Session 與 Cookie:從經營雜貨店開始](https://hulitw.medium.com/session-and-cookie-15e47ed838bc) * [Difference between Stateless and Stateful Protocol](https://www.geeksforgeeks.org/difference-between-stateless-and-stateful-protocol/) ::: success :crescent_moon: 本站內容僅為個人學習記錄,如有錯誤歡迎留言告知、交流討論! :::
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.