无法通过密钥获取gorilla会话值

无法通过密钥获取gorilla会话值,go,gorilla,Go,Gorilla,我无法通过这种方式从会话中获取值,它是nil: session := initSession(r) valWithOutType := session.Values[key] 完整代码: package main import ( "fmt" "github.com/gorilla/mux" "github.com/gorilla/sessions" "log" "

我无法通过这种方式从会话中获取值,它是
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
valWithOutType: %!s(<nil>)
cannot get session value by key: key
value from session
然后我打开url
http://localhost:3000/getSession
并获取输出:

set session with key key and value value
valWithOutType: %!s(<nil>)
cannot get session value by key: key
value from session
initSession()
函数中,您可以更改存储选项:

store.Options = &sessions.Options{
    MaxAge:   3600 * 1, // 1 hour
    HttpOnly: true,
}
该结构还包含一个重要的
路径
字段,cookie将应用于该字段。如果不进行设置,其默认值将为空字符串:
”。这很可能会导致cookie与您的任何URL/路径都不匹配,因此无法找到您现有的会话

添加与所有URL匹配的路径,如下所示:

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

func init() {
    store.Options = &sessions.Options{
        Path:     "/",      // to match all requests
        MaxAge:   3600 * 1, // 1 hour
        HttpOnly: true,
    }
}
另外,您不应该在每次调用
initSession()
时更改
store.Options
,因为您在每个传入请求中都调用了它。只需在创建
存储时设置一次,如下所示:

store.Options = &sessions.Options{
    Path:     "/",      // to match all requests
    MaxAge:   3600 * 1, // 1 hour
    HttpOnly: true,
}
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存储,而是使用redis存储进行会话。我找到了完整的工作示例

主程序包
进口(
“fmt”
“github.com/aaudis/goredission”
“日志”
“net/http”
)
变量(
redis_会话*rsess.SessionConnect
)
func main(){
//可配置参数
rsess.Prefix=“sess://会话前缀(在Redis中)
rsess.Expire=1800//30分钟会话到期
//连接到Redis并创建存储实例
温度,误差:=rsess.New(“sid”,0,“127.0.0.1”,6379)
如果错误!=零{
log.Printf(“%s”,错误)
}
redis\u session=temp\u sess//assing to global variable
http.HandleFunc(“/”,根)
http.HandleFunc(“/get”,get)
http.HandleFunc(“/set”,set)
http.HandleFunc(“/des”,des)
http.listendServe(“:8888”,无)
}
func Root(w http.ResponseWriter,r*http.Request){
w、 Header().Add(“内容类型”、“文本/html”)
格式Fprintf(w`
Redis会话存储示例:



`) } //销毁会话 func Des(w http.ResponseWriter,r*http.Request){ s:=redis_session.session(w,r) s、 销毁(w) fmt.Fprintf(w,“会话已删除!”) } //将变量设置为会话 func集(w http.ResponseWriter,r*http.Request){ s:=redis_session.session(w,r) s、 设置(“用户ID”、“1000”) Fprintf(w,“设置会话变量完成!”) } //从会话获取变量 func Get(w http.ResponseWriter,r*http.Request){ s:=redis_session.session(w,r) fmt.Fprintf(w,“值%s”,s.Get(“用户ID”)) }
您可能正在使用get方法在init session函数中执行的操作是重新启动整个会话,因此每次执行该操作时,会话都是空的。我快速浏览了一下你写的内容,告诉你错误在哪里。请围绕这个例子工作

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
}

我对您的代码玩了很长时间,最后发现它不起作用,因为您将加密密钥设置为非法值

在报告中说:

加密密钥(如果设置)必须为16、24或32字节才能选择AES-128、AES-192或AES-256模式

因此,因为我认为
var encKey=[]字节(“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>`
主程序包
进口(
“fmt”
“github.com/gorilla/mux”
“github.com/gorilla/sessions”
“html/模板”
“日志”
“net/http”
)
var authKey=[]字节(“机密”)//授权密钥
//var encKey=[]字节(“encKey”)//加密密钥
var存储会话
func main(){
rtr:=mux.NewRouter()
rtr.HandleFunc(“/setSession/”,handler1.Methods(“GET”)
rtr.HandleFunc(“/getSession/”,handler2.Methods(“GET”)
http.Handle(“/”,rtr)
store=GetCookieStore()
log.Println(“侦听…”)
http.ListenAndServe(“:4000”,http.DefaultServeMux)
}
//开设烹饪店
func GetCookieStore()会话。存储{
//最大值:=3600*1//1小时
最大年龄:=100
//cookieStore:=sessions.NewCookieStore(authKey,encKey)
cookieStore:=sessions.NewCookieStore(authKey)
cookieStore.Options.HttpOnly=true
cookieStore.Options.Path=“/”//匹配所有请求
cookieStore.MaxAge(MaxAge)
返回库克商店
}
func handler1(w http.ResponseWriter,r*http.Request){
t、 @template.New(“foo”).Parse(getSessionTemplate)
设置会话值(w、r、“键”、“值”)
会话:=initSession(r)
格式打印(“handler1:”)
fmt.Println(会议)
值,确定:=session.Values[“key”]。(字符串)
如果!好的{
Println(“字符串的类型断言失败或无法检索会话值。”)
}
t、 执行(w,值)
}
func handler2(w http.ResponseWriter,r*http.Request){
w、 写入([]字节(“getSession”))
会话:=initSession(r)
格式打印(“handler2:”)
fmt.Println(会议)
值:=GetSessionValue(w,r,“键”)
fmt.Println(“来自会话的值”)
格式打印项次(值)
}
func initSession(r*http.Request)*sessions.Session{
会话,错误:=store.Get(r,“\u golang\u cookie”)
如果错误!=零{
恐慌(错误)
}
返回会话
}
func SetSessionValue(w http.ResponseWriter,r*http.Request,键,值字符串){
会话:=initSession(r)
session.Values[键]=值
fmt.Printf(“使用键%s和值%s设置会话\n”,键,值)
session.Save(r,w)
格式打印(“设置会话:”)
fmt.Println(会议)
}
func GetSessionValue(w http.ResponseWriter,r*http.Request,键字符串)字符串{
会话:=initSession(r)
fmt.Print(“getsession:”)
fmt.Println(会议)
valWithOutType:=会话.值[键]
fmt.Printf(“valwithout类型:%s\n”,valwithout类型)
值,确定:=valWithOutType。(字符串)
如果!好的{
fmt.Println(“无法通过键:“+key”获取会话值)
}
返回值
}
变量