英文:
Go Namespace/Scope Issue for Global Session Management Across Multiple Packages
问题
首先,让我说一下,我是新手使用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)
log.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()
}
package globalsessionkeeper
import (
"github.com/astaxie/beego/session"
_ "github.com/astaxie/beego/session/mysql"
)
//Global Variable
var GlobalSessions *session.Manager
下面是登录函数/包的一部分。当一切都在一个包中时,这个函数/包工作得非常好:
if validated == true {
//使用包含cookie/sessionid的请求数据创建会话
sessionStore, err := globalsessionkeeper.GlobalSessions.SessionStart(w, r)
if err != nil {
//这里需要记录日志而不是打印
fmt.Printf("Error, could not start session %v\n", err)
break
}
defer sessionStore.SessionRelease(w) //在请求完成后更新数据库
if sessionStore.Get("uniquevalue") == nil {
//这里需要记录日志而不是打印
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 {
//这里需要记录日志而不是打印
fmt.Printf("Error while writing to DB, %v\n", err)
break
}
} else {
//这里需要记录日志而不是打印
fmt.Printf("Found Session! Session uniquevalue = %v\n", sessionStore.Get("uniquevalue"))
}
//返回204无内容(带有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
当然,多次调用response.WriteHeader是我必须纠正的另一个问题。最初,go例程发送的是200OK,但是我想将其更改为204无内容,但是一旦我这样做,它就给我报错了。
希望能得到帮助。谢谢!
英文:
First let me say I'm new to Golang. Working with it for a couple of weeks now. Really like the language but...
I'm having some trouble with global session management in Golang. I see how it works and I can me it work if scope is all in one package, however I just recently created new packages for each of my go files. I did this because I read this is best practice and good for reusability.
Ever since I moved the go files into their own packages instead of one package, the session management broke. It looks to create a new session every time instead of reusing an existing session. Here's some code to give you an understanding of what I'm doing:
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()
}
package globalsessionkeeper (I created this just so I can reuse a global variable within all other packages..i.e "package login"..etc)
package globalsessionkeeper
import (
"github.com/astaxie/beego/session"
_ "github.com/astaxie/beego/session/mysql"
)
//Global Variable
var GlobalSessions *session.Manager
Here's a snipit from the login function/package. This was working perfectly fine with everything was in one package:
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)
}
The database has the correctly entry. It has the unique value stored for each session that it creates. Here's some output as well:
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
And of course, the multiple response.WriteHeader is something else I have to correct. The go routine was originally sending a 200OK but I wanted to change that to a 204 no content, however it started giving me that error once I did.
Any help would be appreciated. Thanks!
答案1
得分: 0
原来一直都是有效的。我把错误的 cookie 值传回了 API。愚蠢的错误会引起各种麻烦。
英文:
Turns out this was working all along. I was passing the wrong cookie value back to the api. Silly mistakes cause all kinds of headaches.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论