beego の Session モジュールを使うには Cookie は必要なのか?

スポンサーリンク

はじめに

表題の通りなのですが、まず一次情報元としては下記。

301 Moved Permanently

ここには下記のような記載があります。

The session module is used to store user data between different requests. It only supports saving the session id into a cookie, so if the client doesn’t support cookies, it won’t work.

[Google 翻訳]
セッションモジュールは、異なるリクエスト間でユーザーデータを保存するために使用されます。 セッションIDのCookieへの保存のみをサポートしているため、クライアントがCookieをサポートしていない場合は機能しません。

つまり、Cookie を使わないと Session モジュールは使えないらしい。

ところが、実際には同じページにも記載があるが、enableSetCookie というパラメータがあり、これを true にしないと SetCookie が有効になりません。
つまり、enableSetCookie: false だと Cookie を使うことなく Session 機能が使えることになります。
(Request Header / Response Header で SessionID を送ります)
そして、自分は実際に使っていて概ね動作しています。

要するに、ここまでの話だと、実際には Cookie なしでも Session 機能は使えるので、冒頭のドキュメントの記載が間違っているのではないか?という話になります。

SessionRegenerateID

冒頭のドキュメントにも記載がありますが、SessionRegenerateID というメソッドがあります。
このメソッドは SessionID を新しく生成し直すことができるものです。
結論から言うと、このメソッドは Cookie を使っていないと正常に機能してくれません。

実際のコードは下記のように書かれています。

func (manager *Manager) SessionRegenerateID(w http.ResponseWriter, r *http.Request) (session Store) {
        sid, err := manager.sessionID()
        if err != nil {
                return
        }
        cookie, err := r.Cookie(manager.config.CookieName)
        if err != nil || cookie.Value == "" {
                //delete old cookie
                session, _ = manager.provider.SessionRead(sid)
                cookie = &http.Cookie{Name: manager.config.CookieName,
                        Value:    url.QueryEscape(sid),
                        Path:     "/",
                        HttpOnly: !manager.config.DisableHTTPOnly,
                        Secure:   manager.isSecure(r),
                        Domain:   manager.config.Domain,
                }
        } else {
                oldsid, _ := url.QueryUnescape(cookie.Value)
                session, _ = manager.provider.SessionRegenerate(oldsid, sid)
                cookie.Value = url.QueryEscape(sid)
                cookie.HttpOnly = true
                cookie.Path = "/"
        }
        if manager.config.CookieLifeTime > 0 {
                cookie.MaxAge = manager.config.CookieLifeTime
                cookie.Expires = time.Now().Add(time.Duration(manager.config.CookieLifeTime) * time.Second)
        }
        if manager.config.EnableSetCookie {
                http.SetCookie(w, cookie)
        }
        r.AddCookie(cookie)

        if manager.config.EnableSidInHTTPHeader {
                r.Header.Set(manager.config.SessionNameInHTTPHeader, sid)
                w.Header().Set(manager.config.SessionNameInHTTPHeader, sid)
        }

        return
}

cookie, err := r.Cookie(manager.config.CookieName)
if err != nil || cookie.Value == “” {

上記の部分では、Cookie を取得し、取得できなかった場合に if ブロックが実行されます。
従って、Cookie を使っていない場合にはこのブロックが実行されることになります。
このブロックでは単純に SessionRead して Cookie を作っているだけですので、要するに Session の新規作成と何ら変わりません。

SessionID の再生成は else ブロックの方で実装されているのですが、Cookie を使っていない場合には else ブロックは通ってくれないので、SessionID の再生成を行うためには Cookie を使う必要があるという結論になります。

結論

要するに何が言いたいのかと言うと、、、、beego の Session モジュールを使うには結局のところ、Cookie が必須なのかそうではないのか!?をはっきりしたいということです。
現状、一部(大部分?)の機能は Cookie なしで使えているので、なかなか悩ましいところです。

もともとはドキュメントの通り Cookie 必須の機能だったけど、少しずつ Cookie なしでも使えるように改良中ということなのですかね??
ご存知の方がいらっしゃれば情報いただきたいです。

コメント

タイトルとURLをコピーしました