簡短版
- Cookie是存儲在瀏覽器的數(shù)據(jù),會跟隨HTTP請求發(fā)送到服務(wù)器
- Session是存儲在服務(wù)器端的一系列數(shù)據(jù),通常和指定的用戶相關(guān)聯(lián)(通過Cookie里的值)
詳細版
Cookie
HTTP 協(xié)議是無狀態(tài)的,為了讓 HTTP 協(xié)議盡可能簡單,使得它能夠處理大量事務(wù)。HTTP/1.1 引入 Cookie 來保存狀態(tài)信息。
Cookie 是服務(wù)器發(fā)送到瀏覽器并保存在本地的一小塊數(shù)據(jù)(最大的存儲容量是4KB),瀏覽器在之后向同一個服務(wù)器請求時會攜帶 Cookie 里存儲的信息,用于標識請求是否來自與同一瀏覽器。
除了能接收服務(wù)器端傳輸?shù)?Cookie 之外,瀏覽器也可以通過 document.cookie
創(chuàng)建新的 Cookie,同時也能通過該屬性訪問非 HttpOnly (標記為 HttpOnly 的 Cookie 不能被 js 腳本調(diào)用,可以在一定程度上避免跨站腳本攻擊(XSS)) 的 Cookie。
Cookie 按照其生命周期通常分為兩種
- 會話期 Cookie:瀏覽器關(guān)閉之后會自動刪除,僅在會話器有效
- 持久性 Cookie:指定了過期時間和有效期的 Cookie
Session
Session 和 Cookie 類似,都是用來存儲一些用戶的信息。Session 存儲在服務(wù)器端,存儲在服務(wù)器端會讓這些信息更加安全。Session 可以存儲在服務(wù)器的內(nèi)存、數(shù)據(jù)庫和文件當(dāng)中,也可以存在 Redis 這種內(nèi)存型數(shù)據(jù)庫中,效率會更高。
每一個 Session 都有一個唯一的 Session ID,用于查找、回溯存儲的值。Session 被創(chuàng)建時,它的 Session ID 會以 Cookie 的形式返回給瀏覽器,如果瀏覽器不支持或者禁用了 Cookie,則會把 Session ID 放在 URL 參數(shù)里進行傳遞。
Session 維護用戶登錄信息的例子
- 用戶登錄,提交用戶名和密碼的表單,放到 HTTP 請求報文,發(fā)送登錄的 HTTP 請求
- 服務(wù)器驗證用戶名和密碼,如果校驗成功,則把用戶信息存儲在 Redis 中,用戶信息在 Redis 中的 Key 即為 Session ID
- 服務(wù)器返回 HTTP 響應(yīng),并在響應(yīng)頭中將 Session ID 作為Cookie 的值返回給客戶端,客戶端收到請求之后將 Session ID 存儲在 Cookie 當(dāng)中
- 客戶端在后續(xù)的請求中會攜帶該 Cookie 值,服務(wù)器收到請求后會根據(jù) Session ID 在 Redis 中取出用戶信息,然后進行后續(xù)的業(yè)務(wù)操作
Cookie VS Session
Cookie | Session |
---|---|
Cookie 存儲在客戶端 | Session 存儲在服務(wù)器端 |
Cookie 只能存儲 ASCII 字符串 | Session 可以存儲任意類型的數(shù)據(jù) |
Cookie 最大能夠存儲4KB | Session 能夠存儲的最大容量一般沒有限制 |
- Session 將信息存儲在服務(wù)器,一定程度上要比 Cookie 更加安全
- Session 存儲的數(shù)據(jù)類型要更多,因此在考慮復(fù)雜性的時候會優(yōu)先選擇 Session
- Cookie 不需要依賴 Session 就可以使用, 而 Session 通常會依賴于 Cookie,通過 Cookie 傳遞 Session ID(瀏覽器不支持或者禁用 Cookie時,Session ID 可以通過 URL 參數(shù)里進行傳遞)