こんばんは、七色メガネです。
今回はgolangでクッキーの操作を行なってみます。
前回のチャットアプリの記事と関係あるかと言われれば、ちょっと関係あったりします。
が、今回はまた別にプログラムを組んでるので、本記事単体で読んでもらって問題はありません。
Cookieとは?
正式名称は HTTPCookie です。
HTTPなどの通信プロトコルにおいて、ウェブブラウザに保存される情報のことを指します。
Cookieは、サーバからHTTPヘッダの一部としてサーバからクライアントに対して発行されます。以降クライアントはこのCookieに情報を格納してサーバと通信することにより、ユーザの状態などをサーバに伝えることができます。
CookieはIPアドレスに因らずにクライアントの識別を可能にするため、主にログイン情報などの管理に用いられます。それ以外のデータのやりとりも可能ではあるものの、ヘッダに格納されることと、ヘッダに格納する際にASCIIに変換する必要があることから、データ全体ではなくログインなどのセッション関連のデータが主にこのCookieを用いてやりとりされることが多いようです。
Cookieの操作
では実際にCookieを操作してみたいと思います。
今回は操作を確認するために、こんな画面を作成してみました。
・まず青い色のコンテナですが、ここでは文字列の入力と、入力内容の送信と、クッキーの削除が行えます。
文字列を入力して送信ボタンを押すとサーバにデータが送信され、サーバ側がクッキーにそのデータを保存するという仕組みです。
削除ボタンを押すと、クッキーの内容が削除されます。
・緑色のコンテナでは、クッキーに文字データが保存されていた場合にそれを表示します。
初期状態、またはクッキーの削除後では表示するものが何もないので、表示を行いません。
Cookieの設定
最初にCookieの設定です。Cookieを設定するときは、次の段階を踏みます。
- http.Cookie型へのポインタ変数を用意し、値を設定する。
- http.SetCookie 関数で、Response にポインタ変数を書き込む。
次がサンプルコードです。ブラウザからの入力値を取り出し、http.Cookie型のポインタ変数に設定を行なっています。そしてそれをレスポンスに書き込むという処理を行なっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/* formから文字列を読み取り、クッキーに詰めてから元のページに リダイレクトさせるハンドラ。 */ func showHandler(w http.ResponseWriter, r *http.Request) { r.ParseForm() input := r.FormValue("msg") data := &http.Cookie{ Name: "msg", Value: input, Path: "/", } http.SetCookie(w, data) w.Header()["Location"] = []string{"/"} w.WriteHeader(http.StatusTemporaryRedirect) } |
これで、意図したデータをCookieに書き込むことができました。
Cookieの取得
次の設定したCookieの値を取得します。ここでの操作は一つだけです。
- http.Request に実装されている Cookie(name string) メソッドを使用する。Cookie 設定時に Name 値に設定した文字列を http.Request.Cookie(str string) の引数に渡すことで、対象のCookieを取得できる。
今回は Name を “msg” で保存しているので、Cookieの保存されたRequestで Cookie(“msg”) を実行することで、対象のCookieが取得できます。
次がサンプルコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
func (t *templateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // テンプレートディレクトリを指定する path, err := filepath.Abs("./") if err != nil { panic(err) } // 指定された名称のテンプレートファイルを一度だけコンパイルする t.once.Do( func() { t.tmpl = template.Must(template.ParseFiles(path + t.filename)) }) data := map[string]interface{}{ "Host": r.Host, } // クッキーに入力文字が保存されていれば、ページに反映させる。 msg, err := r.Cookie("msg") if msg != nil { data["msg"] = msg.Value } // テンプレートをパースする際、テンプレートに渡すデータも指定する。 t.tmpl.Execute(w, data) } |
一番下の方で、Cookieの取り出しを行なっています。
今回はCookie経由で取り出したデータをページに反映させるため、dataという変数に設定していますが、Cookieの操作自体には関係ありません。
Cookieの削除
最後に設定したCookieの削除です。ここでの操作も一つだけです。
- http.Cookie へのポインタ変数を呼び出し、Cookieを設定したNameの各要素に対して “”(空白) で上書きを行う。
以下がサンプルコードです。
1 2 3 4 5 6 7 8 9 |
func deleteHandler(w http.ResponseWriter, r *http.Request) { http.SetCookie(w, &http.Cookie{ Name: "msg", Value: "", Path: "", }) w.Header()["Location"] = []string{"/"} w.WriteHeader(http.StatusTemporaryRedirect) } |
先ほどCookieのName:”msg” にブラウザからの入力値を設定していましたので、ここではそれを空白で上書きしています。これで設定したCookieが削除されます。
テスト
では、用意したCookie操作用のプログラムを使用してブラウザでのテストを行なってみます。
まずは初期状態です。Cookieには値が設定されていませんので、緑のコンテナには何も表示がされていません。
次のブラウザのテキストボックスに文字を入力し、送信ボタンを押してみます。
すると緑のコンテナに、送信した文字列が表示されます。これは Cookie から文字データを読み込んで設定している箇所になるので、Cookie経由で適切に文字データをやりとりできていることがわかります。
また、Cookieの内容はChromeであればDeveloperツールのApplicationタブから確認することもできます。
最後に、用意された DeleteCookie のボタンを押して設定したCookieを削除します。
緑のコンテナでは表示する文字列がなくなったので表示はなくなり、DeveloperToolでも対象のValueが削除されたことが分かります。
まとめ
- Cookieの設定
http.Cookie へのポインタ変数を用意し、Nameを指定した上でValueにデータを格納する。
その上で、Cookie へのポインタをレスポンスに書き込む。 - Cookieの取得
http.Request に用意されている Cookie(name string) 関数を使用して、Cookieを取得する。引数のnameには、Cookieに自分で設定したName値を指定する。 - Cookieの削除
Cookieの設定と同じ要領で、Value値に空白を上書きする。 - Cookieの確認
Chromeでは、DeveloperTool のApplicationタブの中にCookiesの項目があり、そこからCookieの中身を確認できる。
以上です。ここまでご覧いただき、ありがとうございました!
使用したsrc
こちらに上げておきます。
https://github.com/NanairoMegane/ctlCookieTest
参考
今回書いたコードと直接の関係はありませんが、次の書籍を読んでいるときにCookieでつまづいたことがきっかけで本記事となりましたので、参考として上げます。