Golang使用MysqlStore的会话不起作用。

huangapple go评论83阅读模式
英文:

Golang sessions with MysqlStore not working

问题

我在一个请求中设置了会话,然后在另一个页面请求中获取会话时遇到了问题。

我正在使用mysqlstore包,这是在gorilla sessions的GitHub页面上在其自述文件的“Store Implementations”部分推荐的。

https://github.com/srinathgs/mysqlstore

我设置了一个简单的请求来测试它,但它不起作用。以下是代码:

HomeController

func (this *HomeController) SetCookie(ctx types.AppContext) web.HandlerType {

    return func(c web.C, w http.ResponseWriter, r *http.Request) {

        w.Header().Set("Content-Type", "text/plain")

        fmt.Printf("%v\n\n", r)
        ctx.SetCookies(r, w)
    }
}

func (this *HomeController) GetCookie(ctx types.AppContext) web.HandlerType {

    return func(c web.C, w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/plain")

        fmt.Printf("%v\n\n", r)
        ctx.GetCookies(r)
    }
}

types.AppContext

func (this *AppContext) SetCookies(r *http.Request, w http.ResponseWriter) {

    fmt.Println("Setting cookies")
    session, _ := this.store.Get(r, "session-name")
    // 设置一些会话值。
    session.Values["foo"] = "bar"
    session.Values[42] = 43
    // 在写入响应/从处理程序返回之前保存会话。
    err := session.Save(r, w)

    if err != nil {
	    fmt.Println("Problem Saving session data")
    }

}
func (this *AppContext) GetCookies(r *http.Request) {

    session, _ := this.store.Get(r, "session-name")
    fmt.Println("Getting cookies")
    // 获取一些会话值
    for k, v := range session.Values {
        fmt.Println("Key:", k)
        fmt.Println("Value:", v)
    }

}

main.go

ctx.SetStore("sessions", "/", 3600, []byte("somesecret"))

....

goji.Get("/set-cookie", homeCtrl.SetCookie(ctx))
goji.Get("/get-cookie", homeCtrl.GetCookie(ctx))

当我访问这两个页面时,没有出现错误,并且我可以在数据库中看到会话已保存。然而,当我尝试检索保存的cookie时,session.Values映射为空。

当我打印出请求时,我得到以下结果(为了方便查看进行了格式化):

&{
    GET /get-cookie HTTP/1.1 1 1 
    map[
        Connection:[keep-alive] 
        User-Agent:[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.107 Safari/537.36] 
        Cookie:[session-name=MTQ0MDQ4MjU0M3xCUXdBQWpJM3x3xeRstTXbooJerGOhzP2pvEmqIkisE1XjS76zI365pA==] 
        Accept-Language:[en,en-CA;q=0.8,en-US;q=0.6,ja;q=0.4] 
        Cache-Control:[max-age=0] 
        Accept:[text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8] 
        Upgrade-Insecure-Requests:[1] 
        Accept-Encoding:[gzip, deflate, sdch]
    ] 
    0x66a9a0 0 [] 
    false localhost:8000 map[] 
    map[] 
    <nil> 
    map[] 
    [::1]:62375 
    /get-cookie 
    <nil>
}

如你所见,我发送了一个名为"session-name"的cookie。在Chrome中,当我查看cookie时,我也可以在本地看到它。

名称:session-name
值:MTQ0MDQ4MjU0M3xCUXdBQWpJM3x3xeRstTXbooJerGOhzP2pvEmqIkisE1XjS76zI365pA
域:localhost
路径:/
过期时间/最大年龄:2015-08-25T07:02:23.347Z(我测试时大约是晚上10:50到11:00)

我一直在研究这个问题,但无法弄清楚为什么它不起作用。按照示例,这应该是很简单的,但它却不起作用。在我的代码中是否有什么遗漏导致它无法工作?

英文:

I am having issues setting sessions on one request and getting them on another page request.

I am using the mysqlstore package which was recommended on the gorilla sessions github page under the "Store Implementations" section in there readme file.

https://github.com/srinathgs/mysqlstore

I setup a simple request to test it out and it wasn't working. Here is the code:

HomeController

func (this *HomeController) SetCookie(ctx types.AppContext) web.HandlerType {

    return func(c web.C, w http.ResponseWriter, r *http.Request) {

        w.Header().Set(&quot;Content-Type&quot;, &quot;text/plain&quot;)

        fmt.Printf(&quot;%v\n\n&quot;, r)
        ctx.SetCookies(r, w)
    }
}

func (this *HomeController) GetCookie(ctx types.AppContext) web.HandlerType {

    return func(c web.C, w http.ResponseWriter, r *http.Request) {
        w.Header().Set(&quot;Content-Type&quot;, &quot;text/plain&quot;)

        fmt.Printf(&quot;%v\n\n&quot;, r)
        ctx.GetCookies(r)
    }
}

types.AppContext

func (this *AppContext) SetCookies(r *http.Request, w http.ResponseWriter) {

    fmt.Println(&quot;Setting cookies&quot;)
    session, _ := this.store.Get(r, &quot;session-name&quot;)
    // Set some session values.
    session.Values[&quot;foo&quot;] = &quot;bar&quot;
    session.Values[42] = 43
    // Save it before we write to the response/return from the handler.
    err := session.Save(r, w)

    if err != nil {
	    fmt.Println(&quot;Problem Saving session data&quot;)
    }

}
func (this *AppContext) GetCookies(r *http.Request) {

    session, _ := this.store.Get(r, &quot;session-name&quot;)
    fmt.Println(&quot;Getting cookies&quot;)
    // get some session values
    for k, v := range session.Values {
        fmt.Println(&quot;Key:&quot;, k)
        fmt.Println(&quot;Value:&quot;, v)
    }

}

main.go

ctx.SetStore(&quot;sessions&quot;, &quot;/&quot;, 3600, []byte(&quot;somesecret&quot;))

....

goji.Get(&quot;/set-cookie&quot;, homeCtrl.SetCookie(ctx))
goji.Get(&quot;/get-cookie&quot;, homeCtrl.GetCookie(ctx))

When I visit both pages I get no errors and I can see in the database a session was saved. However, when I try to retrieve the saved cookie, the session.Values map is empty.

When I print out the request I get the following (formatted for easy viewing):

&amp;{
    GET /get-cookie HTTP/1.1 1 1 
    map[
        Connection:[keep-alive] 
        User-Agent:[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.107 Safari/537.36] 
        Cookie:[session-name=MTQ0MDQ4MjU0M3xCUXdBQWpJM3x3xeRstTXbooJerGOhzP2pvEmqIkisE1XjS76zI365pA==] 
        Accept-Language:[en,en-CA;q=0.8,en-US;q=0.6,ja;q=0.4] 
        Cache-Control:[max-age=0] 
        Accept:[text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8] 
        Upgrade-Insecure-Requests:[1] 
        Accept-Encoding:[gzip, deflate, sdch]
    ] 
    0x66a9a0 0 [] 
    false localhost:8000 map[] 
    map[] 
    &lt;nil&gt; 
    map[] 
    [::1]:62375 
    /get-cookie 
    &lt;nil&gt;
}

As you can see I am sending a cookie and it is the "session-name" one. In Chrome when I look at the cookies I can see it locally as well.

Name: session-name
Value: MTQ0MDQ4MjU0M3xCUXdBQWpJM3x3xeRstTXbooJerGOhzP2pvEmqIkisE1XjS76zI365pA
Domain: localhost
Path: /
Expires/Max-Age: 2015-08-25T07:02:23.347Z (it was about 10:50pm - 11:00pm when I tested this out)

I have been looking at this and can't figure out why it doesn't work. This is as simple as I can make it and according to the examples this should work but it doesn't. Is there something I am missing in my code to make it work?

答案1

得分: 1

我通过一些调查找到了解决方法。当我在mysqlstore包中记录一些错误时,我发现了这个小错误,它引导我找到了解决方案:

panic: sql: Scan error on column index 2: unsupported driver -> Scan pair: []uint8 -> *time.Time

然后我在谷歌上搜索了一下,并在这里找到了一个关于这个问题的讨论:

https://github.com/go-sql-driver/mysql/issues/9

基本上,我没有仔细阅读示例。这个问题一直在包的Readme文件中。我忘记在我的mysql连接凭据的末尾添加查询字符串?parseTime=true&loc=Local

所以基本上,设置数据库时解决方案是:

db, err := sql.Open("mysql", "username:password@/dbname?parseTime=true&loc=Local")
英文:

So I figured it out with some digging around. When I was logging some errors within the mysqlstore package I found this little error which led me to the solution:

panic: sql: Scan error on column index 2: unsupported driver -&gt; Scan pair: []uint8 -&gt; *time.Time

I then googled around a bit and found a discussion on the issue here:

https://github.com/go-sql-driver/mysql/issues/9

Basically I didn't read the Examples too well. This was in the packages Readme file the whole time. I forgot to add the query string ?parseTime=true&amp;loc=Local at the end of my mysql connection credentials.

So basically the solution was this when setting up my database:

db, err := sql.Open(&quot;mysql&quot;, &quot;username:password@/dbname?parseTime=true&amp;loc=Local&quot;)

huangapple
  • 本文由 发表于 2015年8月25日 14:25:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/32196888.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定