【问题标题】:Go Namespace/Scope Issue for Global Session Management Across Multiple Packages跨多个包的全局会话管理的命名空间/范围问题
【发布时间】:2015-08-21 13:23:15
【问题描述】:

首先让我说我是 Golang 的新手。现在用它工作了几个星期。真的很喜欢这种语言,但是...

我在 Golang 中的全局会话管理方面遇到了一些问题。我知道它是如何工作的,如果范围都在一个包中,我可以让它工作,但是我最近刚刚为我的每个 go 文件创建了新包。我这样做是因为我读到这是最佳实践并且有利于可重用性。

自从我将 go 文件移动到它们自己的包而不是一个包中之后,会话管理就中断了。它看起来每次都创建一个新会话,而不是重用现有会话。这里有一些代码可以让你了解我在做什么:

package main

import (
    "net/http"
    "api/login"
    "api/globalsessionkeeper"
    "github.com/astaxie/beego/session"
)

func main() {
    http.HandleFunc("/login", login.DoLogin)

    og.Fatal(http.ListenAndServe(":8000", nil))
}

func Index(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
}

func init() {
    var err error
    fmt.Println("Session init")
    globalsessionkeeper.GlobalSessions, err = session.NewManager("mysql", `{"enableSetCookie":true, "SessionOn":true, "cookieName":"globalsession_id","gclifetime":120,"ProviderConfig":"root@tcp(172.16.0.23:3306)/databse"}`)
    if err != nil {
        fmt.Printf("Error")
    }
    globalsessionkeeper.GlobalSessions.SetSecure(true)
    go globalsessionkeeper.GlobalSessions.GC()
}

包 globalsessionkeeper(我创建这个只是为了我可以在所有其他包中重用一个全局变量..即“包登录”..etc)

package globalsessionkeeper

import (
    "github.com/astaxie/beego/session"
    _ "github.com/astaxie/beego/session/mysql"
)

//Global Variable
var GlobalSessions *session.Manager

这是登录功能/包中的一个片段。一切都在一个包中,这一切都很好:

if validated == true {
    //create session using the request data which includes the cookie/sessionid
    sessionStore, err := globalsessionkeeper.GlobalSessions.SessionStart(w, r)
    if err != nil {
        //need logging here instead of print
        fmt.Printf("Error, could not start session %v\n", err)
        break
    }
    defer sessionStore.SessionRelease(w) //update db upon completion for request

    if sessionStore.Get("uniquevalue") == nil {
        //need logging here instead of print
        fmt.Printf("uniquevalue not found, Saving Session, Get has %v\n", sessionStore)
        fmt.Printf("uniquevalue not found, Saving Session, Get has %v\n", sessionStore.Get("uniquevalue"))
        err = sessionStore.Set("uniquevalue", input.uniquevalue)
        if err != nil {
            //need logging here instead of print
            fmt.Printf("Error while writing to DB, %v\n", err)
            break
        }
    } else {
        //need logging here instead of print
        fmt.Printf("Found Session! Session uniquevalue = %v\n", sessionStore.Get("uniquevalue"))
    }
    //Send back 204 no content (with cookie)
    w.WriteHeader(http.StatusNoContent)
} else {
    fmt.Printf("Login Failed")
    w.WriteHeader(http.StatusUnauthorized)
}

数据库有正确的条目。它具有为其创建的每个会话存储的唯一值。这里还有一些输出:

answer = true
uniquvalue not found, Saving Session, Get has &{0xc208046b80 f08u0489804984988494994 {{0 0} 0 0 0 0} map[]}
uniquevalue not found, Saving Session, Get has <nil>
2015/06/06 17:32:26 http: multiple response.WriteHeader calls

当然,多重响应。WriteHeader 是我必须纠正的其他问题。 go 例程最初发送 200OK 但我想将其更改为 204 无内容,但是一旦我这样做,它就开始给我这个错误。

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 为什么不用beego的路由系统呢?您可以直接通过上下文对象访问会话。无需创建全局会话包。
  • “为我的每个 go 文件创建了新包”。我希望这是一个错字,您并没有真正将每个 *.go 文件放在它自己的包中。 在有意义的地方使用包,也就是说,它是一个具有清晰 API 的独立概念和/或其他东西想要/需要使用包是合理的。此外,globalsessionkeeper 是一个贫穷且不惯用的 name for a Go package
  • 你能解释一下吗?如果我有登录和注册文件,它们不应该在单独的包中吗?对不起,我是 golang 的新手。我一边走一边试图弄清楚这一点。

标签: web-applications go global-variables session-cookies beego


【解决方案1】:

事实证明这一直有效。我将错误的 cookie 值传递回 api。愚蠢的错误会引起各种头痛。

【讨论】:

    猜你喜欢
    • 2012-05-03
    • 1970-01-01
    • 2020-01-17
    • 2012-10-07
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    相关资源
    最近更新 更多