Cannot get gorilla session value by key

I cannot get the value from the session this way, it is nil :

 session := initSession(r) valWithOutType := session.Values[key] 

Full code:

 package main import ( "fmt" "github.com/gorilla/mux" "github.com/gorilla/sessions" "log" "net/http" ) func main() { rtr := mux.NewRouter() rtr.HandleFunc("/setSession", handler1).Methods("GET") rtr.HandleFunc("/getSession", handler2).Methods("GET") http.Handle("/", rtr) log.Println("Listening...") http.ListenAndServe(":3000", http.DefaultServeMux) } func handler1(w http.ResponseWriter, r *http.Request) { SetSessionValue(w, r, "key", "value") w.Write([]byte("setSession")) } func handler2(w http.ResponseWriter, r *http.Request) { w.Write([]byte("getSession")) value := GetSessionValue(w, r, "key") fmt.Println("value from session") fmt.Println(value) } var authKey = []byte("secret") // Authorization Key var encKey = []byte("encKey") // Encryption Key var store = sessions.NewCookieStore(authKey, encKey) func initSession(r *http.Request) *sessions.Session { store.Options = &sessions.Options{ MaxAge: 3600 * 1, // 1 hour HttpOnly: true, } session, err := store.Get(r, "golang_cookie") if err != nil { panic(err) } return session } func SetSessionValue(w http.ResponseWriter, r *http.Request, key, value string) { session := initSession(r) session.Values[key] = value fmt.Printf("set session with key %s and value %s\n", key, value) session.Save(r, w) } func GetSessionValue(w http.ResponseWriter, r *http.Request, key string) string { session := initSession(r) valWithOutType := session.Values[key] fmt.Printf("valWithOutType: %s\n", valWithOutType) value, ok := valWithOutType.(string) if !ok { fmt.Println("cannot get session value by key: " + key) } return value } 

Conclusion:

 myMac ~/forStack/session $ go run ./session.go 2015/01/30 16:47:26 Listening... 

First, I open the url http://localhost:3000/setSession and get the output:

 set session with key key and value value 

Then I open the url http://localhost:3000/getSession and get the output:

 valWithOutType: %!s(<nil>) cannot get session value by key: key value from session 

Why is valWithOutType equal to zero even though I asked /setSession ?

Update

I changed the code according to @isza's answer, but the session value is still nil .

 package main import ( "fmt" "github.com/gorilla/mux" "github.com/gorilla/sessions" "log" "net/http" ) func main() { rtr := mux.NewRouter() rtr.HandleFunc("/setSession", handler1).Methods("GET") rtr.HandleFunc("/getSession", handler2).Methods("GET") http.Handle("/", rtr) log.Println("Listening...") store.Options = &sessions.Options{ MaxAge: 3600 * 1, // 1 hour HttpOnly: true, Path: "/", // to match all requests } http.ListenAndServe(":3000", http.DefaultServeMux) } func handler1(w http.ResponseWriter, r *http.Request) { SetSessionValue(w, r, "key", "value") w.Write([]byte("setSession")) } func handler2(w http.ResponseWriter, r *http.Request) { w.Write([]byte("getSession")) value := GetSessionValue(w, r, "key") fmt.Println("value from session") fmt.Println(value) } var authKey = []byte("secret") // Authorization Key var encKey = []byte("encKey") // Encryption Key var store = sessions.NewCookieStore(authKey, encKey) func initSession(r *http.Request) *sessions.Session { session, err := store.Get(r, "golang_cookie") if err != nil { panic(err) } return session } func SetSessionValue(w http.ResponseWriter, r *http.Request, key, value string) { session := initSession(r) session.Values[key] = value fmt.Printf("set session with key %s and value %s\n", key, value) session.Save(r, w) } func GetSessionValue(w http.ResponseWriter, r *http.Request, key string) string { session := initSession(r) valWithOutType := session.Values[key] fmt.Printf("valWithOutType: %s\n", valWithOutType) value, ok := valWithOutType.(string) if !ok { fmt.Println("cannot get session value by key: " + key) } return value } 
+5
source share
3 answers

In your initSession() function, you change the storage settings:

 store.Options = &sessions.Options{ MaxAge: 3600 * 1, // 1 hour HttpOnly: true, } 

The Options structure also contains the important Path field to which the cookie will be applied. If you do not install it, its default value will be an empty string: "" . This is likely to cause the cookie to not be matched to any of your URLs, so your existing session will not be found.

Add a path to match all of your URLs:

 store.Options = &sessions.Options{ Path: "/", // to match all requests MaxAge: 3600 * 1, // 1 hour HttpOnly: true, } 

Also, you should not change store.Options in every initSession() call, since you are calling this in every incoming request. Just install this once when you create your store as follows:

 var store = sessions.NewCookieStore(authKey, encKey) func init() { store.Options = &sessions.Options{ Path: "/", // to match all requests MaxAge: 3600 * 1, // 1 hour HttpOnly: true, } } 
+1
source

As I did not find the answer, I decided not to use cookie storage, but use redis store for sessions. And I found a complete working example here

 package main import ( "fmt" "github.com/aaudis/GoRedisSession" "log" "net/http" ) var ( redis_session *rsess.SessionConnect ) func main() { // Configurable parameters rsess.Prefix = "sess:" // session prefix (in Redis) rsess.Expire = 1800 // 30 minute session expiration // Connecting to Redis and creating storage instance temp_sess, err := rsess.New("sid", 0, "127.0.0.1", 6379) if err != nil { log.Printf("%s", err) } redis_session = temp_sess // assing to global variable http.HandleFunc("/", Root) http.HandleFunc("/get", Get) http.HandleFunc("/set", Set) http.HandleFunc("/des", Des) http.ListenAndServe(":8888", nil) } func Root(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "text/html") fmt.Fprintf(w, ` Redis session storage example:<br><br> <a href="/set">Store key in session</a><br> <a href="/get">Get key value from session</a><br> <a href="/des">Destroy session</a> `) } // Destroy session func Des(w http.ResponseWriter, r *http.Request) { s := redis_session.Session(w, r) s.Destroy(w) fmt.Fprintf(w, "Session deleted!") } // Set variable to session func Set(w http.ResponseWriter, r *http.Request) { s := redis_session.Session(w, r) s.Set("UserID", "1000") fmt.Fprintf(w, "Setting session variable done!") } // Get variable from session func Get(w http.ResponseWriter, r *http.Request) { s := redis_session.Session(w, r) fmt.Fprintf(w, "Value %s", s.Get("UserID")) } 
+1
source

What you probably do in your init session function using the get method, you restart the entire session again, so every time you do this, the session is empty. I quickly hacked what you wrote to show you where your mistake is. Please get around this example!

 package appSession import ( "net/http" "fmt" "log" "github.com/gorilla/sessions" ) var appSession *sessions.Session; var authKey = []byte("qwer") var encKey = []byte("asdf") var store = sessions.NewCookieStore(authKey, encKey) func initSession(r *http.Request) *sessions.Session { log.Println("session before get", appSession) if appSession == nil { }else{ return appSession; } session, err := store.Get(r, "golang_cookie") appSession = session; log.Println("session after get", session) if err != nil { panic(err) } return session } func SetSessionValue(w http.ResponseWriter, r *http.Request, key, value string) { session := initSession(r) session.Values[key] = value fmt.Printf("set session with key %s and value %s\n", key, value) session.Save(r, w) } func GetSessionValue(w http.ResponseWriter, r *http.Request, key string) string { session := initSession(r) valWithOutType := session.Values[key] fmt.Printf("valWithOutType: %s\n", valWithOutType) value, ok := valWithOutType.(string) log.Println("returned value: ", value); if !ok { fmt.Println("cannot get session value by key: " + key) } return value } 
0
source

Source: https://habr.com/ru/post/1212275/


All Articles