最近Golangにハマっていて、特にechoというフレームワークを使ってみよう!と思って、echoに手を出してみました。で、ドキュメントの上の方に書いてあり、またwebサービスを作るのであれば必須になるCookieをまず初めに触ってみようと思いまして、今回実際に使ってみました。
Cookie
ドキュメントには以下のように書いてあります。
Create a Cookie
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") }
new(http.Cookie)をして、パラメータ(attributes)を入力(assigning)して、最後にc.SetCookie(cookies)を実行するだけで、HTTPレスポンスヘッダーのSet-Cookieに追加されます。
Read a Cookie
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") }
c.Cookie("username")を呼ぶだけでHTTPリクエストヘッダーから取得することができます。
実際にやってみる
という感じに書いてあったので、実際にスクリプトを書いてみました。
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 }
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) }
上のプログラムを簡単にまとめると
- /cookie/set/:nameでcookieにnameを入れる
- /cookie/getでcookieに入っているものを出力する
というもの。
これを実際に実行してみました。もちろんブラウザ上でURLを入力して試しています。
GET: http://localhost:9999/cookie/set/test
write a cookie: test
GET: http://localhost:9999/cookie/get
{"message":"Internal Server Error"}
あれ?Internal Server Errorになっちゃいました。。
いろいろ調査してみると、
GET: http://localhost:9999/cookie/set/test
これのレスポンスヘッダを見てみると
Set-Cookie: username=test; Expires=Tue, 24 Apr 2018 17:29:47 GMT
GET: http://localhost:9999/cookie/get
これのリクエストヘッダを見てみても受け取ったCookieを渡していません。
もしかして、path属性が/cookie/setになっているのかも!?
あとからみて気づいたのですが、ドキュメントにも書いてあるPathというCookie Attributeを指定してあげることで解決できます。
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) }
このようにcookei.Path = "/"を入れてあげます。
すると
GET: http://localhost:9999/cookie/set/test
このレスポンスヘッダは
Set-Cookie: username=test; Path=/; Expires=Tue, 24 Apr 2018 17:40:02 GMT
という感じにPath=/;が追加されました。ということなので、
GET: http://localhost:9999/cookie/get
にアクセスすると
write a cookie: test
と無事ブラウザに出力されるようになりました。
まとめ
何が悪かったかというと、Path属性をちゃんと理解してなかったというところ。
Pathをちゃんと指定してあげれば簡単に解決できた問題だったのです。
ということで、これでセッション管理のベース部分をちょっとだけ踏み込めた気がします。やったね!