簡(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)大家多多支持。