I cannot get value from 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
}
Output:
myMac ~/forStack/session $ go run ./session.go
2015/01/30 16:47:26 Listening...
First I open url http://localhost:3000/setSession
and get output:
set session with key key and value value
Then I open url http://localhost:3000/getSession
and get output:
valWithOutType: %!s(<nil>)
cannot get session value by key: key
value from session
Why valWithOutType
is nil, although I set it requesting /setSession
?
I changed code according to @isza answer, but 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
}
What you are probably doing in your init session function with the get method you are restarting the whole session again so every time you do it the session is empty. I did a quick hack around what you wrote to show you where your error is. Please work 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 {
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
}
In your initSession()
function you change the store options:
store.Options = &sessions.Options{
MaxAge: 3600 * 1, // 1 hour
HttpOnly: true,
}
The Options
struct also contains an important Path
field to which the cookie will apply. If you don't set it, its default value will be the empty string: ""
. This will most likely cause that the cookie will not be matched with any of your urls/paths, so your existing session will not be found.
Add a path to match all your urls like this:
store.Options = &sessions.Options{
Path: "/", // to match all requests
MaxAge: 3600 * 1, // 1 hour
HttpOnly: true,
}
Also you shouldn't change store.Options
in each call of initSession()
since you call this in each incoming request. Just set this once when you create your store
like this:
var store = sessions.NewCookieStore(authKey, encKey)
func init() {
store.Options = &sessions.Options{
Path: "/", // to match all requests
MaxAge: 3600 * 1, // 1 hour
HttpOnly: true,
}
}
As I have not found answer I decided not to use cookie store but use redis store for sessions. And I found full 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"))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With