【问题标题】:gorilla/sessions: Session be managed (persist changes) between handlers?gorilla/sessions:在处理程序之间管理会话(保持更改)?
【发布时间】:2017-08-21 10:02:14
【问题描述】:

我正在使用 Go 会话管理:

"github.com/gorilla/sessions"

以下代码的问题是与 CookieStore 关联的会话没有在处理程序之间共享,我需要它来这样做。

处理程序"/authorize" 将值保存到会话中,然后重定向到另一个处理程序"/thankyou",但该处理程序在会话中看不到该值。

我已验证会话在原始处理程序 "/authorize" 中确实具有新值。

import (
    "github.com/gorilla/sessions"
)

var (
    cookieStore *sessions.CookieStore
    storeGUID   string
    sessionGUID string
)

func init() {
    storeGUID = "{random-string}"
    sessionGUID = "{random-string}"
    cookieStore = sessions.NewCookieStore([]byte(storeGUID))
}

mux.HandleFunc("/authorize", func(w http.ResponseWriter, r *http.Request) {
    var sess *sessions.Session
    sess, err := cookieStore.Get(r, sessionGUID)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    sess.Values["authMode"] = "Authorized"

    if err := sess.Save(r, w); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // Redirect to "/thankyou"
    authorizeURL := r.URL.String()
    thankyouRedirectURL := strings.Replace(authorizeURL, "authorize", "thankyou", 1)
    defer http.Redirect(w, r, thankyouRedirectURL, http.StatusFound)
}

mux.HandleFunc("/thankyou", func(w http.ResponseWriter, r *http.Request) {
    var sess *sessions.Session
    sess, err := cookieStore.Get(r, sessionGUID)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    var sval interface{}
    var authMode string

    sval = sess.Values["authMode"]
    if authMode, ok := sval.(string); !ok {
        err := errors.New("Missing \"authSess\" in session.")
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
}

【问题讨论】:

    标签: session go gorilla


    【解决方案1】:

    我的网络服务器遇到了同样的问题。我正在做你正在做的事情:

    sval = sess.Values["authMode"]
    if authMode, ok := sval.(string); !ok {
        err := errors.New("Missing \"authSess\" in session.")
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    

    我创建了一个局部变量来存储检索到的会话值,然后键入断言该值以确保其完整性。我发现类型断言静默失败,因为 gorilla/sessions.Session 结构的 Values 字段的类型为map[interface{}]interface{} (source)。从 Values 字段中检索会话值时,就像您在此处所做的那样...

    sval = sess.Values["authMode"]
    

    ...编译器认为 sval 现在属于 interface{} 类型。因此,当您尝试键入 assert sval 时,它无法将接口转换为字符串。

    我所做的是在我处理类型断言的 if 块上方创建一个变量声明,以便我以后可以使用它。然后,我使用 map 元素本身键入 assert。这就是你的样子:

    var authMode string // a var declaration with the type you want
    var ok bool         // in my case, I also created a bool var to avoid a pointer error
    
    // directly type assert the session value
    if authMode, ok = sess.Values["authMode"].(string); !ok {
        err := errors.New("Missing \"authSess\" in session.")
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    

    希望对你有帮助!

    【讨论】:

    • 感谢您的回复。您是说会话可以在处理程序之间持续存在吗?而我只是错误地请求值?
    • @jeff00seattle 当然可以。是的,我是说会话可以持续存在,这只是如何访问值的问题。
    • @[Forest Hoffman] 我想我发现了我的问题,它必须处理cookieStore = sessions.NewCookieStore([]byte(storeGUID)),在 Chrome 浏览器中查看会话时它没有创建 cookie。不知道从这里去哪里。涉及更多研究。
    • 好的,我想我的问题是 cookie 没有被创建。
    • 我在 gorilla/sessions 存储库中搜索了您的“gob type not registered”错误并找到了github issue。我不知道原始代码是否包含任何其他会话设置器,但也许注册您拥有的任何类型都值得一试。
    猜你喜欢
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 2016-02-04
    • 2020-08-26
    • 2012-12-09
    • 1970-01-01
    • 2012-09-11
    相关资源
    最近更新 更多