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

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

Golang sessions with MysqlStore not working

问题

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

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

https://github.com/srinathgs/mysqlstore

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

HomeController

  1. func (this *HomeController) SetCookie(ctx types.AppContext) web.HandlerType {
  2. return func(c web.C, w http.ResponseWriter, r *http.Request) {
  3. w.Header().Set("Content-Type", "text/plain")
  4. fmt.Printf("%v\n\n", r)
  5. ctx.SetCookies(r, w)
  6. }
  7. }
  8. func (this *HomeController) GetCookie(ctx types.AppContext) web.HandlerType {
  9. return func(c web.C, w http.ResponseWriter, r *http.Request) {
  10. w.Header().Set("Content-Type", "text/plain")
  11. fmt.Printf("%v\n\n", r)
  12. ctx.GetCookies(r)
  13. }
  14. }

types.AppContext

  1. func (this *AppContext) SetCookies(r *http.Request, w http.ResponseWriter) {
  2. fmt.Println("Setting cookies")
  3. session, _ := this.store.Get(r, "session-name")
  4. // 设置一些会话值。
  5. session.Values["foo"] = "bar"
  6. session.Values[42] = 43
  7. // 在写入响应/从处理程序返回之前保存会话。
  8. err := session.Save(r, w)
  9. if err != nil {
  10. fmt.Println("Problem Saving session data")
  11. }
  12. }
  13. func (this *AppContext) GetCookies(r *http.Request) {
  14. session, _ := this.store.Get(r, "session-name")
  15. fmt.Println("Getting cookies")
  16. // 获取一些会话值
  17. for k, v := range session.Values {
  18. fmt.Println("Key:", k)
  19. fmt.Println("Value:", v)
  20. }
  21. }

main.go

  1. ctx.SetStore("sessions", "/", 3600, []byte("somesecret"))
  2. ....
  3. goji.Get("/set-cookie", homeCtrl.SetCookie(ctx))
  4. goji.Get("/get-cookie", homeCtrl.GetCookie(ctx))

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

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

  1. &{
  2. GET /get-cookie HTTP/1.1 1 1
  3. map[
  4. Connection:[keep-alive]
  5. 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]
  6. Cookie:[session-name=MTQ0MDQ4MjU0M3xCUXdBQWpJM3x3xeRstTXbooJerGOhzP2pvEmqIkisE1XjS76zI365pA==]
  7. Accept-Language:[en,en-CA;q=0.8,en-US;q=0.6,ja;q=0.4]
  8. Cache-Control:[max-age=0]
  9. Accept:[text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8]
  10. Upgrade-Insecure-Requests:[1]
  11. Accept-Encoding:[gzip, deflate, sdch]
  12. ]
  13. 0x66a9a0 0 []
  14. false localhost:8000 map[]
  15. map[]
  16. <nil>
  17. map[]
  18. [::1]:62375
  19. /get-cookie
  20. <nil>
  21. }

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

  1. 名称:session-name
  2. 值:MTQ0MDQ4MjU0M3xCUXdBQWpJM3x3xeRstTXbooJerGOhzP2pvEmqIkisE1XjS76zI365pA
  3. 域:localhost
  4. 路径:/
  5. 过期时间/最大年龄:2015-08-25T07:02:23.347Z(我测试时大约是晚上10:5011: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

  1. func (this *HomeController) SetCookie(ctx types.AppContext) web.HandlerType {
  2. return func(c web.C, w http.ResponseWriter, r *http.Request) {
  3. w.Header().Set(&quot;Content-Type&quot;, &quot;text/plain&quot;)
  4. fmt.Printf(&quot;%v\n\n&quot;, r)
  5. ctx.SetCookies(r, w)
  6. }
  7. }
  8. func (this *HomeController) GetCookie(ctx types.AppContext) web.HandlerType {
  9. return func(c web.C, w http.ResponseWriter, r *http.Request) {
  10. w.Header().Set(&quot;Content-Type&quot;, &quot;text/plain&quot;)
  11. fmt.Printf(&quot;%v\n\n&quot;, r)
  12. ctx.GetCookies(r)
  13. }
  14. }

types.AppContext

  1. func (this *AppContext) SetCookies(r *http.Request, w http.ResponseWriter) {
  2. fmt.Println(&quot;Setting cookies&quot;)
  3. session, _ := this.store.Get(r, &quot;session-name&quot;)
  4. // Set some session values.
  5. session.Values[&quot;foo&quot;] = &quot;bar&quot;
  6. session.Values[42] = 43
  7. // Save it before we write to the response/return from the handler.
  8. err := session.Save(r, w)
  9. if err != nil {
  10. fmt.Println(&quot;Problem Saving session data&quot;)
  11. }
  12. }
  13. func (this *AppContext) GetCookies(r *http.Request) {
  14. session, _ := this.store.Get(r, &quot;session-name&quot;)
  15. fmt.Println(&quot;Getting cookies&quot;)
  16. // get some session values
  17. for k, v := range session.Values {
  18. fmt.Println(&quot;Key:&quot;, k)
  19. fmt.Println(&quot;Value:&quot;, v)
  20. }
  21. }

main.go

  1. ctx.SetStore(&quot;sessions&quot;, &quot;/&quot;, 3600, []byte(&quot;somesecret&quot;))
  2. ....
  3. goji.Get(&quot;/set-cookie&quot;, homeCtrl.SetCookie(ctx))
  4. 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):

  1. &amp;{
  2. GET /get-cookie HTTP/1.1 1 1
  3. map[
  4. Connection:[keep-alive]
  5. 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]
  6. Cookie:[session-name=MTQ0MDQ4MjU0M3xCUXdBQWpJM3x3xeRstTXbooJerGOhzP2pvEmqIkisE1XjS76zI365pA==]
  7. Accept-Language:[en,en-CA;q=0.8,en-US;q=0.6,ja;q=0.4]
  8. Cache-Control:[max-age=0]
  9. Accept:[text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8]
  10. Upgrade-Insecure-Requests:[1]
  11. Accept-Encoding:[gzip, deflate, sdch]
  12. ]
  13. 0x66a9a0 0 []
  14. false localhost:8000 map[]
  15. map[]
  16. &lt;nil&gt;
  17. map[]
  18. [::1]:62375
  19. /get-cookie
  20. &lt;nil&gt;
  21. }

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.

  1. Name: session-name
  2. Value: MTQ0MDQ4MjU0M3xCUXdBQWpJM3x3xeRstTXbooJerGOhzP2pvEmqIkisE1XjS76zI365pA
  3. Domain: localhost
  4. Path: /
  5. 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

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

  1. 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:

  1. 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:

确定