會話控制利器 gorilla/sessions

Aklman發表於2021-07-12

推薦 gorilla/sessions 的背景

在日常 Web 應用開發過程中,需要對使用者登入狀態進行判斷,而 HTTP 是無狀態的,即不記錄使用者登入狀態,想要得到使用者登入狀態得把登入狀態儲存下來,通常使用者狀態資料加密後用資料庫或者快取等手段把儲存;原生的會話資料儲存的 HTTP cookie 對資料大小有限制,不能寫入太多太大的資料,又不能對儲存的資料進行有效管理,而 gorilla/sessions 恰恰補充了原生回話控制的不足。

gorilla/sessions 簡介

gorilla/sessions 支援原生的 HTTP cookie 會話資料儲存和儲存介質系統會話以及自定義會話等基礎設施(Memcache/Redis/SQLite/MySQL )的支援應有盡有。

gorilla/sessions 提供了會話資料的加密解密,以及底層的 cookie 管理,提供的介面比較簡單易用,gorilla/sessions 主要特點如下:

  • 簡單的 API:使用它作為設定簽名(和可選的加密)cookie 的簡單方法。
  • 內建的後端可以在 cookie 或檔案系統中儲存會話。
  • Flash 資訊:會話值持續到讀取為止。
  • 切換會話永續性(又稱 "記住我")和設定其他屬性的方便方法。
  • 輪換認證和加密金鑰的機制。
  • 每個請求有多個會話,甚至使用不同的後端。
  • 自定義會話後端的介面和基礎設施:來自不同端的會話可以使用一個共同的 API 進行檢索和批量儲存。

gorilla/sessions 應用

下面是整合 gorilla/sessions 的簡單會話控制業務程式碼段,如下:

import (
    "github.com/gorilla/sessions"
    "net/http"
    "os"
)

// Store gorilla sessions 的儲存庫
var Store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))

// Session 當前會話
var Session *sessions.Session

// Request 用以獲取會話
var Request *http.Request

// Response 用以寫入會話
var Response http.ResponseWriter

// StartSession 初始化會話
func StartSession(w http.ResponseWriter, r *http.Request) {
    Store, _ := Store.Get(r, "session-name")
    // Set some session values.
    Session.Values["foo"] = "bar"
    Session.Values[42] = 43
    //外部可以這麼設定
    //Set("foo","bar")
    //Set("age", 22)
    // Save it before we write to the response/return from the handler.
    session.Save(r, w)

    Request = r
    Response = w
    //Save(Request, Response)
}

// Set 寫入鍵值對應的會話資料
func Set(key interface{}, value interface{}) {
    Session.Values[key] = value
    Save()
}

// Get 獲取會話資料,獲取資料時請做型別檢測
func Get(key string) interface{} {
    return Session.Values[key]
}

// Destroy 刪除某個會話項
func Destroy(key string) {
    delete(Session.Values, key)
    Save()
}

// Save 保持會話
func Save() {
    Session.Save(Request, Response)
}

注意:非 HTTPS 的連結無法使用 Secure 和 HttpOnly,瀏覽器會報錯,因此非 HTTPS 要設定

Session.Options.Secure = true
Session.Options.HttpOnly = true

首先,初始化一個會話儲存,呼叫 NewCookieStore() 並傳遞一個用於驗證會話的祕密金鑰。其次,在處理器中呼叫 store.Get() 來檢索一個現有的會話或建立一個新的會話,在 session.Values 中設定一些會話值,它是一個 map[interface{}] interface{} 。最後,我們呼叫 session.Save() 來儲存響應中的會話。

值得注意的是,

  • 在生產程式碼中,應該在呼叫 session.Save(r, w) 時檢查是否有錯誤,並顯示錯誤資訊或以其他方式處理。
  • 會話資料被儲存在 map[string] interface{}中,所以在檢索資料時需要對其進行型別驗證。
  • Save 必須在寫入響應之前呼叫,否則會話 cookie 將不會被髮送到客戶端。

預設情況下,會話 cookies 持續一個月。這可能對有些情況來說可能太長了,但在執行時很容易改變 cookies 持續時間和其他相關屬性。會話可以被單獨配置,也可以服務提供者哪裡配置,然後所有使用它儲存的會話都將使用該配置。具體地呼叫 session.Options 或 store.Options 來設定一個新的配置。

總結

gorilla/sessions 支援原生的 cookie 會話資料儲存和檔案系統會話以及自定義會話功能,可以在主流的 Go Web 框架或者自創的框架及應用上可以直接拿來就可以使用。

參考資料


歡迎加入 GOLANG 中國社群:https://gocn.vip

更多原創文章乾貨分享,請關注公眾號
  • 會話控制利器 gorilla/sessions
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章