GO-會話控制
- 2020 年 4 月 8 日
- 筆記
第 7 章:會話控制
HTTP 是無狀態協議,伺服器不能記錄瀏覽器的訪問狀態,也就是說伺服器不能區分中兩次請求是否由一個客戶端發出。這樣的設計嚴重阻礙的 Web 程式的設計。如:在我們進行網購時,買了一條褲子,又買了一個手機。由於 http 協議是無狀態的,如果不通過其他手段,伺服器是不能知道用戶到底買了什麼。而 Cookie 就是解決方案之一。
7.1 Cookie
7.1.1 簡介
Cookie 實際上就是伺服器保存在瀏覽器上的一段資訊。瀏覽器有了 Cookie 之後,每次向伺服器發送請求時都會同時將該資訊發送給伺服器,伺服器收到請求後,就可以根據該資訊處理請求。

7.1.2 Cookie 的運行原理
- 第一次向伺服器發送請求時在伺服器端創建 Cookie
- 將在伺服器端創建的 Cookie 以響應頭的方式發送給瀏覽器
- 以後再發送請求瀏覽器就會攜帶著該 Cookie
- 伺服器得到 Cookie 之後根據 Cookie 的資訊來區分不同的用戶
7.1.3 創建 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) }
7.1.4 讀取 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]
7.1.5 設置 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
7.1.6 Cookie 的用途
- 廣告推薦
- 免登錄
7.2 Session
7.2.1 簡介
使用 Cookie 有一個非常大的局限,就是如果 Cookie 很多,則無形的增加了客戶端與服務端的數據傳輸量。而且由於瀏覽器對 Cookie 數量的限制,註定我們不能再Cookie 中保存過多的資訊,於是 Session 出現。
Session 的作用就是在伺服器端保存一些用戶的數據,然後傳遞給用戶一個特殊的 Cookie,這個 Cookie 對應著這個伺服器中的一個 Session,通過它就可以獲取到保存用戶資訊的 Session,進而就知道是那個用戶再發送請求。
7.2.2 Session 的運行原理
- 第一次向伺服器發送請求時創建 Session,給它設置一個全球唯一的 ID(可以通過UUID 生成)
- 創建一個 Cookie,將 Cookie 的 Value 設置為 Session 的 ID 值,並將 Cookie 發送給瀏覽器
- 以後再發送請求瀏覽器就會攜帶著該 Cookie
- 伺服器獲取 Cookie 並根據它的 Value 值找到伺服器中對應的 Session,也就知道了請求是那個用戶發的