ポンコツエンジニアのごじゃっぺ開発日記。

いろいろポンコツだけど、気にするな。プログラム&ロボット大好きなポンコツが日々の記録を残していきます。 自動で収入を得られるサービスやシステムを作ることが目標!!

Go言語フレームワークechoのcookieでつまずいた話。

最近Golangにハマっていて、特にechoというフレームワークを使ってみよう!と思って、echoに手を出してみました。で、ドキュメントの上の方に書いてあり、またwebサービスを作るのであれば必須になるCookieをまず初めに触ってみようと思いまして、今回実際に使ってみました。

 

Cookie

ドキュメントには以下のように書いてあります。

Create a Cookie

[code]

func writeCookie(c echo.Context) error {   cookie := new(http.Cookie)   cookie.Name = "username"   cookie.Value = "jon"   cookie.Expires = time.Now().Add(24 * time.Hour)   c.SetCookie(cookie)   return c.String(http.StatusOK, "write a cookie") }

[/code]

new(http.Cookie)をして、パラメータ(attributes)を入力(assigning)して、最後にc.SetCookie(cookies)を実行するだけで、HTTPレスポンスヘッダーのSet-Cookieに追加されます。

 

Read a Cookie

[code] func readCookie(c echo.Context) error {   cookie, err := c.Cookie("username")   if err != nil {     return err   }   fmt.Println(cookie.Name)   fmt.Println(cookie.Value)   return c.String(http.StatusOK, "read a cookie") } [/code]

c.Cookie("username")を呼ぶだけでHTTPリクエストヘッダーから取得することができます。

 

実際にやってみる

という感じに書いてあったので、実際にスクリプトを書いてみました。

[code title="route/router.go"] package route

import( "github.com/labstack/echo" "github.com/labstack/echo/middleware"

"../controller" )

func Init() *echo.Echo { e := echo.New()

e.Use(middleware.Logger()) e.Use(middleware.Recover())

e.GET("/cookie/set/:name", controller.WriteCookie) e.GET("/cookie/get", controller.ReadCookie)

return e } [/code]

[code title="controller/cookie.go"] package controller

import ( "net/http" "fmt" "time" "github.com/labstack/echo" )

func WriteCookie(c echo.Context) error { name := c.Param("name") cookie := new(http.Cookie) cookie.Name = "username" cookie.Value = name cookie.Expires = time.Now().Add(24 * time.Hour) c.SetCookie(cookie)

return c.String(http.StatusOK, "write a cookie: " + name) }

func ReadCookie(c echo.Context) error { cookie, err := c.Cookie("username") if err != nil { fmt.Println(err) return err } fmt.Println(cookie.Name) fmt.Println(cookie.Value) return c.String(http.StatusOK, "read a cookie: " + cookie.Value) } [/code]

上のプログラムを簡単にまとめると

というもの。

 

これを実際に実行してみました。もちろんブラウザ上でURLを入力して試しています。

 

[code title="GET: http://localhost:9999/cookie/set/test"]

write a cookie: test

[/code]

[code title="GET: http://localhost:9999/cookie/get"]

{"message":"Internal Server Error"}

[/code]

あれ?Internal Server Errorになっちゃいました。。

いろいろ調査してみると、

GET: http://localhost:9999/cookie/set/test

これのレスポンスヘッダを見てみると

[code]

Set-Cookie: username=test; Expires=Tue, 24 Apr 2018 17:29:47 GMT

[/code]

GET: http://localhost:9999/cookie/get

これのリクエストヘッダを見てみても受け取ったCookieを渡していません。

もしかして、path属性が/cookie/setになっているのかも!?

あとからみて気づいたのですが、ドキュメントにも書いてあるPathというCookie Attributeを指定してあげることで解決できます。

[code firstline="10" highlight="16"] func WriteCookie(c echo.Context) error { name := c.Param("name") cookie := new(http.Cookie) cookie.Name = "username" cookie.Value = name cookie.Expires = time.Now().Add(24 * time.Hour) cookie.Path = "/" c.SetCookie(cookie)

return c.String(http.StatusOK, "write a cookie: " + name) } [/code]

このようにcookei.Path = "/"を入れてあげます。

すると

GET: http://localhost:9999/cookie/set/test

このレスポンスヘッダは

[code]

Set-Cookie: username=test; Path=/; Expires=Tue, 24 Apr 2018 17:40:02 GMT

[/code]

という感じにPath=/;が追加されました。ということなので、

GET: http://localhost:9999/cookie/get

にアクセスすると

[code]

write a cookie: test

[/code]

と無事ブラウザに出力されるようになりました。

 

まとめ

何が悪かったかというと、Path属性をちゃんと理解してなかったというところ。

Pathをちゃんと指定してあげれば簡単に解決できた問題だったのです。

ということで、これでセッション管理のベース部分をちょっとだけ踏み込めた気がします。やったね!