Go gorilla/sessions

こんにちは、マットです。
都内ITベンチャーのエンジニアです。
Go/Next.js/GraphQLを使っています。

今回はGoでcookieを扱うパッケージ gorilla/sessionsを触ってみます。https://github.com/gorilla/sessions

最初は公式のサンプルコードを見て、次に用意された構造体やメソッドの中身を見ていきたいと思います。

公式のサンプルコード

以下サンプルコード

var store = sessions.NewCookieStore([]byte("SESSION_KEY"))

func MyHandler(w http.ResponseWriter, r *http.Request) {
    session, _ := store.Get(r, "session-name")
    session.Values["foo"] = "bar"
    session.Values[42] = 43
    err := session.Save(r, w)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
}

上記のhanderを適当なルーティングに割り当てる

func main() {
    http.HandleFunc("/gorilla", MyHandler)
    if err := http.ListenAndServe(":8081", nil); err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

レスポンスを確認

$ curl --head http://localhost:8081/gorilla 


HTTP/1.1 200 OK
Set-Cookie: session-name=MTYzNzQ4MzIxM3xEdi1CQkFFQ180SUFBUkFCRUFBQU1QLUNBQUlEYVc1MEJBSUFWQU5wYm5RRUFnQldCbk4wY21sdVp3d0ZBQU5tYjI4R2MzUnlhVzVuREFVQUEySmhjZz09fJzVsQrt4j5jQV79BAUCBahsc4ZmHKcdrEAIHn56icPZ; Path=/; Expires=Tue, 21 Dec 2021 08:26:53 GMT; Max-Age=2592000
Date: Sun, 21 Nov 2021 08:26:53 GMT

"session-name" keyに対してエンコードされたvalueが保持されている。

Get() メソッドではkeyからSession構造体の取得を行う。該当するkeyがなければ新規に登録される。

Save() メソッドで加工されたSessionを保存している。

Session

Session構造体の中身

// Session stores the values and optional configuration for a session.
type Session struct {
    // The ID of the session, generated by stores. It should not be used for
    // user data.
    ID string
    // Values contains the user-data for the session.
    Values  map[interface{}]interface{}
    Options *Options
    IsNew   bool
    store   Store
    name    string
}

cookieのオプションを設定したい時は Optionsフィールドに値を追加する。

type Options struct {
    Path   string
    Domain string
    // MaxAge=0 means no Max-Age attribute specified and the cookie will be
    // deleted after the browser session ends.
    // MaxAge<0 means delete cookie immediately.
    // MaxAge>0 means Max-Age attribute present and given in seconds.
    MaxAge   int
    Secure   bool
    HttpOnly bool
    // Defaults to http.SameSiteDefaultMode
    SameSite http.SameSite
}

HttpOnly, MaxAge, Secureを設定する。

func MyHandler(w http.ResponseWriter, r *http.Request) {
    session, _ := store.Get(r, "session-name")
    session.Values["foo"] = "bar"
    session.Values[42] = 43

    session.Options.HttpOnly = true
    session.Options.MaxAge = 10000
    session.Options.Secure = true

    err := session.Save(r, w)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
}
$ curl --head http://localhost:8081/gorilla
HTTP/1.1 200 OK
Set-Cookie: session-name=MTYzNzQ4NDM2MXxEdi1CQkFFQ180SUFBUkFCRUFBQU1QLUNBQUlHYzNSeWFXNW5EQVVBQTJadmJ3WnpkSEpwYm1jTUJRQURZbUZ5QTJsdWRBUUNBRlFEYVc1MEJBSUFWZz09fAznLgZpNT7cqWO_KlXh6eVzOo7NfSdwcCvG_Ulp-CCF; Path=/; Expires=Sun, 21 Nov 2021 11:32:41 GMT; Max-Age=10000; HttpOnly; Secure
Date: Sun, 21 Nov 2021 08:46:01 GMT

設定したオプションが無事に付与されている。

簡単ですが以上 gorilla/sessionを触ってみました。

最後に、 このブログではweb開発について発信していくのでまたご覧頂けると嬉しいです。 最後までお読み頂きありがとうございました。