Не может получить значение сеанса гориллы по ключу
Я не могу получить значение от сессии таким образом, это nil
:
session := initSession(r)
valWithOutType := session.Values[key]
Полный код:
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
}
Выход:
myMac ~/forStack/session $ go run ./session.go
2015/01/30 16:47:26 Listening...
Сначала я открываю URL http://localhost:3000/setSession
и получить вывод:
set session with key key and value value
Тогда я открываю URL http://localhost:3000/getSession
и получить вывод:
valWithOutType: %!s(<nil>)
cannot get session value by key: key
value from session
Зачем valWithOutType
ноль, хотя я установил его с просьбой /setSession
?
Обновить
Я изменил код в соответствии с ответом @isza, но значение сеанса по-прежнему 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
}
4 ответа
Что вы, вероятно, делаете в своей функции сеанса инициализации с помощью метода get, вы перезапускаете весь сеанс снова, поэтому каждый раз, когда вы делаете это, сеанс пуст. Я быстро взломал то, что ты написал, чтобы показать, где твоя ошибка. Пожалуйста, обойдите этот пример!
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
}
В вашем initSession()
Функция изменения параметров магазина:
store.Options = &sessions.Options{
MaxAge: 3600 * 1, // 1 hour
HttpOnly: true,
}
Options
структура также содержит важный Path
поле, к которому будет применяться cookie. Если вы не установите его, его значением по умолчанию будет пустая строка: ""
, Скорее всего, это приведет к тому, что файл cookie не будет сопоставлен ни с одним из ваших URL / путей, поэтому существующий сеанс не будет найден.
Добавьте путь, чтобы соответствовать всем вашим URL, как это:
store.Options = &sessions.Options{
Path: "/", // to match all requests
MaxAge: 3600 * 1, // 1 hour
HttpOnly: true,
}
Также не стоит менять store.Options
в каждом вызове initSession()
так как вы звоните это в каждом входящем запросе. Просто установите это один раз, когда вы создаете store
как это:
var store = sessions.NewCookieStore(authKey, encKey)
func init() {
store.Options = &sessions.Options{
Path: "/", // to match all requests
MaxAge: 3600 * 1, // 1 hour
HttpOnly: true,
}
}
Поскольку я не нашел ответа, я решил не использовать cookie store, а использовать redis store для сессий. И я нашел полный рабочий пример здесь
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"))
}
Я долго играл с вашим кодом и, наконец, обнаружил, что он не работает, потому что вы установили для ключа шифрования недопустимое значение.
В документации /gorilla/session написано:
Ключ шифрования, если он установлен, должен иметь размер 16, 24 или 32 байта для выбора режимов AES-128, AES-192 или AES-256.
Так как я считаю, что var encKey = []byte("encKey")
просто не следует этому требованию. В свою очередь, cookie не устанавливается в первую очередь.
Смотрите мой код для справки. Я в основном добавил еще вывод командной строки и использовал шаблон с перенаправлением:
package main
import (
"fmt"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
"html/template"
"log"
"net/http"
)
var authKey = []byte("secret") // Authorization Key
//var encKey = []byte("encKey") // Encryption Key
var store sessions.Store
func main() {
rtr := mux.NewRouter()
rtr.HandleFunc("/setSession/", handler1).Methods("GET")
rtr.HandleFunc("/getSession/", handler2).Methods("GET")
http.Handle("/", rtr)
store = GetCookieStore()
log.Println("Listening...")
http.ListenAndServe(":4000", http.DefaultServeMux)
}
//setting up the cookiestore
func GetCookieStore() sessions.Store {
//maxAge := 3600 * 1 // 1 hour
maxAge := 100
//cookieStore := sessions.NewCookieStore(authKey, encKey)
cookieStore := sessions.NewCookieStore(authKey)
cookieStore.Options.HttpOnly = true
cookieStore.Options.Path = "/" // to match all requests
cookieStore.MaxAge(maxAge)
return cookieStore
}
func handler1(w http.ResponseWriter, r *http.Request) {
t, _ := template.New("foo").Parse(getSessionTemplate)
SetSessionValue(w, r, "key", "value")
session := initSession(r)
fmt.Print("handler1: ")
fmt.Println(session)
Value, ok := session.Values["key"].(string)
if !ok {
fmt.Println("Type assertion to string failed or session value could not be retrieved.")
}
t.Execute(w, Value)
}
func handler2(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("getSession"))
session := initSession(r)
fmt.Print("handler2: ")
fmt.Println(session)
value := GetSessionValue(w, r, "key")
fmt.Println("value from session")
fmt.Println(value)
}
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)
fmt.Print("setsession: ")
fmt.Println(session)
}
func GetSessionValue(w http.ResponseWriter, r *http.Request, key string) string {
session := initSession(r)
fmt.Print("getsession: ")
fmt.Println(session)
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
}
var getSessionTemplate = `
<p><label>Session value set:</label></p>
<p><label>Value: is now: {{.}}</label></p>
<p><a href="/getSession/">Getsession</a></p>`