會話控制 HTTP 是無狀態協議,伺服器不能記錄瀏覽器的訪問狀態,也就是說伺服器不 能區分中兩次請求是否由一個客戶端發出。這樣的設計嚴重阻礙的 Web 程式的設計。 如:在我們進行網購時,買了一條褲子,又買了一個手機。由於 http 協議是無狀態的, 如果不通過其他手段,伺服器是不能知道用戶到底買了 ...
會話控制
HTTP 是無狀態協議,伺服器不能記錄瀏覽器的訪問狀態,也就是說伺服器不
能區分中兩次請求是否由一個客戶端發出。這樣的設計嚴重阻礙的 Web 程式的設計。
如:在我們進行網購時,買了一條褲子,又買了一個手機。由於 http 協議是無狀態的,
如果不通過其他手段,伺服器是不能知道用戶到底買了什麼。而 Cookie 就是解決方案
之一。
Cookie
簡介
Cookie 實際上就是伺服器保存在瀏覽器上的一段信息。瀏覽器有了 Cookie 之後,
每次向伺服器發送請求時都會同時將該信息發送給伺服器,伺服器收到請求後,就可以
根據該信息處理請求。
Cookie 的運行原理
- 第一次向伺服器發送請求時在伺服器端創建 Cookie
- 將在伺服器端創建的 Cookie 以響應頭的方式發送給瀏覽器
- 以後再發送請求瀏覽器就會攜帶著該 Cookie
- 伺服器得到 Cookie 之後根據 Cookie 的信息來區分不同的用戶
創建 Cookie 並將它發送給瀏覽器
- 在伺服器創建 Cookie 並將它發送給瀏覽器
伺服器端代碼
func handler(w http.ResponseWriter, r *http.Request) {
cookie1 := http.Cookie{
Name: "user1",
Value: "admin",
HttpOnly: true,
}
cookie2 := http.Cookie{
Name: "user2",
Value: "superAdmin",
HttpOnly: true,
}
//將 Cookie 發送給瀏覽器,即添加第一個 Cookie
w.Header().Set("Set-Cookie", cookie1.String())
//再添加一個 Cookie
w.Header().Add("Set-Cookie", cookie2.String())
}
瀏覽器響應報文中的內容
HTTP/1.1 200 OK
Set-Cookie: user1=admin; HttpOnly
Set-Cookie: user2=superAdmin; HttpOnly
Date: Sun, 12 Aug 2018 07:24:49 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8
- 以後每次發送請求瀏覽器都會攜帶著 Cookie
GET /cookie HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62
Safari/537.36
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/
apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: user1=admin; user2=superAdmin
- 除了 Set 和 Add 方法之外,Go 還提供了一種更快捷的設置 Cookie 的方式,
就是通過 net/http 庫中的 SetCookie 方法
將 1)中的代碼進行修改
func handler(w http.ResponseWriter, r *http.Request) {
cookie1 := http.Cookie{
Name: "user1",
Value: "admin",
HttpOnly: true,
}
cookie2 := http.Cookie{
Name: "user2",
Value: "superAdmin",
HttpOnly: true,
}
http.SetCookie(w, &cookie1)
http.SetCookie(w, &cookie2)
}
讀取 Cookie
由於我們在發送請求時 Cookie 在請求頭中,所以我們可以通過 Request 結構中的
Header 欄位來獲取 Cookie
- 處理器端代碼
func handler(w http.ResponseWriter, r *http.Request) {
//獲取請求頭中的 Cookie
cookies := r.Header["Cookie"]
fmt.Fprintln(w, cookies)
}
- 瀏覽器中的結果
[user1=admin; user2=superAdmin]
設置 Cookie 的有效時間
Cookie 預設是會話級別的,當關閉瀏覽器之後 Cookie 將失效,我們可以通過 Cookie
結構的 MaxAge 欄位設置 Cookie 的有效時間
- 處理器端代碼
func handler(w http.ResponseWriter, r *http.Request) {
cookie := http.Cookie{
Name: "user",
Value: "persistAdmin",
HttpOnly: true,
MaxAge: 60,
}
//將 Cookie 發送給瀏覽器
w.Header().Set("Set-Cookie", cookie.String())
}
- 瀏覽器響應報文中的內容
HTTP/1.1 200 OK
Set-Cookie: user=persistAdmin; Max-Age=60; HttpOnly
Date: Sun, 12 Aug 2018 07:32:57 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8
Cookie 的用途
- 廣告推薦
- 免登錄
Session
簡介
使用 Cookie 有一個非常大的局限,就是如果 Cookie 很多,則無形的增加了客戶
端與服務端的數據傳輸量。而且由於瀏覽器對 Cookie 數量的限制,註定我們不能再
Cookie 中保存過多的信息,於是 Session 出現。
Session 的作用就是在伺服器端保存一些用戶的數據,然後傳遞給用戶一個特殊
的 Cookie,這個 Cookie 對應著這個伺服器中的一個 Session,通過它就可以獲取到保
存用戶信息的 Session,進而就知道是那個用戶再發送請求。
Session 的運行原理
- 第一次向伺服器發送請求時創建 Session,給它設置一個全球唯一的 ID(可以通過
UUID 生成) - 創建一個 Cookie,將 Cookie 的 Value 設置為 Session 的 ID 值,並將 Cookie 發送
給瀏覽器 - 以後再發送請求瀏覽器就會攜帶著該 Cookie
- 伺服器獲取 Cookie 並根據它的 Value 值找到伺服器中對應的 Session,也就知道了
請求是那個用戶發的