背景
以下の本を読んでいてセッションの話がありました。
今一度正しく理解する為に備忘録として整理します。
本書では自作のセッション管理の処理を実装されていましたが、安全面を考慮してプログラミング言語やフレームワーク側で提供されている処理を推奨されていました。
業務で使用しているGo(Gin)を使ってセッションの処理を実装し、セッション管理のイメージを掴みます。
セッションとは
クライアントとサーバの一連の通信を識別する為の状態管理の単位のことです。
セッションがなぜ必要なのか
HTTPは通信をする際に状態を持ちません(ステートレス)。
セッションを使うことで状態を持つことができます。
今回はセッションをcookieで実現します。
cookieとは
cookieはクライアントとサーバーの間で状態を管理する為に考えられた仕組みです。
図で説明します。
まず、リクエストを送るとサーバーからのレスポンスにcookieが載せられてクライアントのブラウザに保存されます。
再度リクエストを送るとサーバーに先ほど保存したcookieを送ります。
cookieはnameとvalueのペアで情報を持つことができます。
例えばになりますがnameにsessionID,valueにクライアントを識別する値を設定するとcookieでセッションを実現できます。
次に実際にサンプルコードでcookieによるセッションを実現します。
Ginとは
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API, but with performance up to 40 times faster than Martini. If you need smashing performance, get yourself some Gin.
- Goで書かれたHTTPウェブフレームワーク
- パフォーマンスはMartiniの40倍も速い
Ginでセッション管理を実装する
以下のライブラリを使用したいと思います。
今回はcookieでセッションIDを管理する実装をします。
cookie-basedというセクションにサンプルコードが紹介されていました。
このサンプルコードはcookieベースのセッションを使って、/incr へアクセスするたびにカウンタを保存・返すコードです。
package main
import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
store := cookie.NewStore([]byte("secret"))
r.Use(sessions.Sessions("mysession", store))
r.GET("/incr", func(c *gin.Context) {
session := sessions.Default(c)
var count int
v := session.Get("count")
if v == nil {
count = 0
} else {
count = v.(int)
count++
}
session.Set("count", count)
session.Save()
c.JSON(200, gin.H{"count": count})
})
r.Run(":8000")
}
cookie.NewStore
でcookieにセッションを保存します。
つまり「mysession」という名前の Cookie の中身 がそのままセッションの実体です。
session.Save()
でレスポンスヘッダに Set-Cookie: mysession=... を付与します。
// Save adds a single session to the response.
func (s *CookieStore) Save(r *http.Request, w http.ResponseWriter,
session *Session) error {
encoded, err := securecookie.EncodeMulti(session.Name(), session.Values,
s.Codecs...)
if err != nil {
return err
}
http.SetCookie(w, NewCookie(session.Name(), encoded, session.Options))
return nil
}
今回はgo-blueprintでプロジェクトを作成しました。
実際に作ったリポジトリは以下です。
実際に/inc
にアクセスしてcookieの情報を見てみる
その後はリロード(/incにGETリクエストを送る)するたびにカウントアップされることがわかります。
別のブラウザで開くとカウントが0にリセットされます。
つまりcookieによりクライアントを識別しているのでセッションを実現できていることを確認できました。
最後に
- セッションとcookieが混在していたので整理できました
- セッション管理は他にもあるので比較したいです
- cookieの安全な使用方法についてまとめたいです