gorilla/sessions 學(xué)習(xí)筆記

簡(jiǎn)單樣例

  • 首先調(diào)用NewCookieStore初始化一個(gè)store,同時(shí)傳入一個(gè)secret key用來(lái)對(duì)session進(jìn)行認(rèn)證。
  • Handler中,調(diào)用store.Get()獲取一個(gè)已經(jīng)存在的session或(如果不存在)創(chuàng)建一個(gè)新的。
  • 設(shè)置sesssion.Values中的值,session.Values是map[interface{}]interface{}類型。
  • 調(diào)用session.Save()將session保存到響應(yīng)中。

在實(shí)際項(xiàng)目中,調(diào)用session.Save(r,w)時(shí)需要檢測(cè)返回的錯(cuò)誤并處理。
Save()方法必須在寫入response之前調(diào)用,否則session cookie不會(huì)發(fā)送到客戶端。

var store = sessions.NewCookieStore([]byte("something-very-secret"))

func MyHandler(w http.ResponseWriter, r *http.Request) {

    session, err := store.Get(r, "s1")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    fmt.Println(session)
    session.Values["name"] = "kingeastensun"
    session.Save(r, w)
}

func MultiSessionHandler(w http.ResponseWriter, r *http.Request) {
    session1, err := store.Get(r, "s1")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    fmt.Println(session1)
    session1.Values["name"] = "kingeastensun"

    session2, err := store.Get(r, "s2")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    fmt.Println(session2)
    session2.Values["name"] = "kingeastensunyx"
    sessions.Save(r, w)

}

func main() {

    routes := mux.NewRouter()
    routes.HandleFunc("/session", MyHandler)
    routes.HandleFunc("/musession", MultiSessionHandler)

    http.Handle("/", routes)
    http.ListenAndServe(":8080", nil)
}

多session的處理

參見(jiàn)MultiSessionHandler,在保存的時(shí)候,調(diào)用

sessions.Save(r, w)

就可以同時(shí)保存session1和session2。

復(fù)雜結(jié)構(gòu)數(shù)據(jù)

type MPerson struct {
    FirstName string
    LastName  string
    Email     string
    Age       int
}

type M map[string]interface{}

func init() {
    fmt.Println("init")
    gob.Register(&MPerson{})
    gob.Register(&M{})
}

var store = sessions.NewCookieStore([]byte("something-very-secret"))

func SetMHandler(w http.ResponseWriter, r *http.Request) {
    session, err := store.Get(r, "m")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    ms := MPerson{FirstName: "king", LastName: "eastersun"}
    session.Values["ms"] = ms
    m := make(map[string]interface{})
    m["name"] = "kingeasternsun"
    session.Values["m"] = m
    err = session.Save(r, w)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

}

func GetMHandler(w http.ResponseWriter, r *http.Request) {
    session, err := store.Get(r, "m")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    ms := session.Values["ms"]
    // var person = &MPerson{}
    if person, ok := ms.(*MPerson); ok {
        fmt.Println(person)
    } else {

        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    m := session.Values['m']
    // var mmap = M{}
    if mmap, ok := m.(*M); ok {
        fmt.Println(mmap)
    } else {

        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

}

func main() {
    // fmt.Println(string(securecookie.GenerateRandomKey(32)))
    // fmt.Println(string(securecookie.GenerateRandomKey(32)))
    routes := mux.NewRouter()
    routes.HandleFunc("/setm", SetMHandler)
    routes.HandleFunc("/getm", GetMHandler)

    http.Handle("/", routes)
    http.ListenAndServe(":8080", nil)
}

設(shè)置的時(shí)候報(bào)錯(cuò)


瀏覽器報(bào)錯(cuò)

問(wèn)題在于

    m := make(map[string]interface{})
    m["name"] = "kingeasternsun"

map[string]interface{}沒(méi)有注冊(cè)到session,在init中僅僅注冊(cè)了MPersion和M,雖然M的定義方式如下:

type M map[string]interface{}

但是在golang中,這種聲明方式,M和map[string]interface{}屬于不同類型。
修改SetMHandler如下:

func SetMHandler(w http.ResponseWriter, r *http.Request) {
    session, err := store.Get(r, "m")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    ms := MPerson{FirstName: "king", LastName: "eastersun"}
    session.Values["ms"] = ms
    m := M{}
    m = make(map[string]interface{})
    m["name"] = "kingeasternsun"
    session.Values["m"] = m
    err = session.Save(r, w)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

}

cookie設(shè)置成功


cookie設(shè)置成功

獲取cookie失敗

代碼中誤將雙引號(hào)寫成了單引號(hào)

    m := session.Values['m']
    m := session.Values["m"]
獲取cookie成功

key的更換

在項(xiàng)目中可能會(huì)遇到要更換key的需求,sessions也可以方便的實(shí)現(xiàn)

var store = sessions.NewCookieStore(
    []byte("new-authentication-key"),
    []byte("new-encryption-key"),
    []byte("old-authentication-key"),
    []byte("old-encryption-key"),
)

store通過(guò)這樣的創(chuàng)建方法,新的sessions會(huì)通過(guò)一個(gè)key pair進(jìn)行創(chuàng)建,舊的sessions則通過(guò)老的key pair讀取。

對(duì)于所有的key pair, encryption key 是可選的,如果為空或省略,則不好進(jìn)行加密。

后記

之前一直在CSDN上寫文章,后面會(huì)逐步轉(zhuǎn)換到簡(jiǎn)書上,還請(qǐng)大家多多支持。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容