クッキー

Go標準ライブラリのnet/httpパッケージを利用して、クッキー(Cookie)を操作する方法を説明します。

クッキー操作のサンプル

次のクッキーの各種操作のサンプルです。

package main

import (
    "encoding/base64"
    "fmt"
    "net/http"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/set", set)
    mux.HandleFunc("/get", get)
    mux.HandleFunc("/del", del)
    server := http.Server{
        Addr:    ":8080",
        Handler: mux,
    }
    server.ListenAndServe()
}

func set(w http.ResponseWriter, r *http.Request) {
    // クッキーを作成
    a := http.Cookie{
        Name:     "a",
        Value:    base64.URLEncoding.EncodeToString([]byte("cookie a")),
        MaxAge:   0,
        HttpOnly: true,
    }
    b := http.Cookie{
        Name:     "b",
        Value:    base64.URLEncoding.EncodeToString([]byte("cookie b")),
        MaxAge:   0,
        HttpOnly: true,
    }
    // 作成したクッキーをHTTPヘッダに設定
    http.SetCookie(w, &a)
    http.SetCookie(w, &b)
}

func get(w http.ResponseWriter, r *http.Request) {
    // すべてのクッキーを取得
    fmt.Fprintln(w, "# Cookies")
    cookies := r.Cookies()
    for _, c := range cookies {
        v, _ := base64.URLEncoding.DecodeString(c.Value)
        fmt.Fprintf(w, "%v=%v\n", c.Name, string(v))
    }

    // 指定した名前のクッキーを取得
    fmt.Fprintln(w, "# Cookie")
    a, err := r.Cookie("a")
    if err != nil {
        fmt.Fprintln(w, err)
        return
    }
    v, _ := base64.URLEncoding.DecodeString(a.Value)
    fmt.Fprintf(w, "%v=%v\n", a.Name, string(v))

    b, err := r.Cookie("b")
    if err != nil {
        fmt.Fprintln(w, err)
        return
    }
    v, _ = base64.URLEncoding.DecodeString(b.Value)
    fmt.Fprintf(w, "%v=%v\n", b.Name, string(v))

    // クッキーが存在しない場合はエラー
    c, err := r.Cookie("c")
    if err != nil {
        fmt.Fprintln(w, err)
        return
    }
    v, _ = base64.URLEncoding.DecodeString(c.Value)
    fmt.Fprintf(w, "%v=%v\n", c.Name, string(v))
}

func del(w http.ResponseWriter, r *http.Request) {
    // クッキーを削除するにはMaxAgeに負の値を設定
    a := http.Cookie{
        Name:     "a",
        Value:    "",
        MaxAge:   -1,
        HttpOnly: true,
    }
    b := http.Cookie{
        Name:     "b",
        Value:    "",
        MaxAge:   -1,
        HttpOnly: true,
    }
    http.SetCookie(w, &a)
    http.SetCookie(w, &b)
}

以降で個々の操作方法や実行例を確認していきます。

クッキーの取得

クッキーを取得するには、次の変数やメソッドを利用します。

  • Request.Cookies:すべてのクッキーを取得する
  • Request.Cookie:指定した名前のクッキーを取得する

関連コードを抜粋します。

今回はクッキーに保存する値をURLエンコードしているため、取り出す際はデコードします。

// すべてのクッキーを取得
cookies := r.Cookies()
for _, c := range cookies {
    v, _ := base64.URLEncoding.DecodeString(c.Value)
    fmt.Fprintf(w, "%v=%v\n", c.Name, string(v))
}

// 指定した名前のクッキーを取得
a, err := r.Cookie("a")
v, _ := base64.URLEncoding.DecodeString(a.Value)
fmt.Fprintf(w, "%v=%v\n", a.Name, string(v))

それでは実行してみましょう。

http://localhost:8080/getにアクセスし、まだクッキーが設定されてないことを確認します。

# Cookies
# Cookie
http: named cookie not present

以降でクッキーを設定した際の振る舞いを確認します。

クッキーの設定

クッキーを設定するには、次の構造体や関数を利用します。

  • http.Cookie:クッキーを表現する構造体
  • http.SetCookie:クッキーを設定する

関連コードを抜粋します。

必須ではありませんが、クッキーに保存する値はURLエンコードしておきます。

// クッキーを作成
a := http.Cookie{
    Name:     "a",
    Value:    base64.URLEncoding.EncodeToString([]byte("cookie a")),
    MaxAge:   0,
    HttpOnly: true,
}
// 作成したクッキーをHTTPヘッダに設定
http.SetCookie(w, &a)

それでは実行してみましょう。

http://localhost:8080/getにアクセスし、まだクッキーが設定されてないことを確認します。

# Cookies
# Cookie
http: named cookie not present

http://localhost:8080/setにアクセスすると、クッキーが設定されます。

再度、http://localhost:8080/getにアクセスし、クッキーが設定されたことを確認します。

# Cookies
a=cookie a
b=cookie b
# Cookie
a=cookie a
b=cookie b
http: named cookie not present

クッキーの削除

クッキーを削除するには、クッキーのMaxAgeに負の値を設定します。

関連コードを抜粋します。

// クッキーを削除するにはMaxAgeに負の値を設定
a := http.Cookie{
    Name:     "a",
    Value:    "",
    MaxAge:   -1,
    HttpOnly: true,
}
http.SetCookie(w, &a)

それでは実行してみましょう。

http://localhost:8080/getにアクセスし、クッキーが設定されていることを確認します。

# Cookies
a=cookie a
b=cookie b
# Cookie
a=cookie a
b=cookie b
http: named cookie not present

http://localhost:8080/delにアクセスすると、クッキーが削除されます。

http://localhost:8080/getにアクセスし、クッキーが削除されたことを確認します。

# Cookies
# Cookie
http: named cookie not present