💭

go で Cookie を理解する

2023/07/09に公開

Cookie と検索するとあらゆるメディアが Cookie について書いてある中あえて Cookie の記事を書こうと思いました。

今回は Go を用いて Cookie を理解していきます。

MDN より

HTTP Cookie (ウェブ Cookie、ブラウザー Cookie) は、サーバーがユーザーのウェブブラウザーに送信する小さなデータであり、ブラウザーに保存され、その後のリクエストと共に同じサーバーへ返送されます。一般的には、 2 つのリクエストが同じブラウザーから送信されたものであるかを知るために使用されます。例えば、ユーザーのログイン状態を維持することができます。 Cookie は、ステートレスな HTTP プロトコルのためにステートフルな情報を記憶します。

https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies

「ログイン状態を維持する」と書かれてありますが、この記事で書くのは普通に状態を維持したいケースです。

用意したコードは以下です。
https://github.com/UserKazun/go_experiments/blob/main/main.go

実装はかなりシンプルで、/experiments/hello などにアクセスすると Cookie が付与されます。
そして、/hello にアクセスしたときに Cookie が見つかればページを表示します。

この実装は、例えば本番環境で新規機能の QA などがしたいときは、特に役立ちます。
IP 制限(今回の実装には含めていません)と Cookie 付与によってユーザーはアクセスができないが、社内の人間ならアクセスできるという状況が作れるので、特にバグが出ても問題になりません。
環境によっては、stg とローカルでアプリケーションの構造が違っていたりして、stg では起きなかった問題が、本番では起きるなど起こり得るので、このような Cookie の使い方は非常に役に立ちます。

Path 属性を考えて付与する

Cookie には属性があります。
https://www.javadrive.jp/javascript/webpage/index18.html

今回のような Cookie のような使い方をする場合 Path 属性の付与は必須となります。
Path 属性は Cookie を送信するパスのことです。

例えば /experiments となっているなら、 /experiments にアクセスしたときだけ Cookie を送信します。これをどこのパスにアクセスしても Cookie を送信したい場合は / を Path 属性に指定することで実現できます。

そのほかの属性

先述した Path 以外にも色々な属性があります。
https://www.javadrive.jp/javascript/webpage/index18.html

セキュリティのための Domain、Secure、HttpOnly や Cookie の有効期限を指定する Expire などです。
この辺りは上記の記事を見るとわかると思います。

セッションとは何か

ついでに Cookie とよくセットで話されるセッションについても触れておこうと思います。
セッションとは「ユーザーがログインする→商品を選ぶ→カードに入れる→購入する」などといった処理の流れのことを言います。

Http がステートレスであることは先述しましたが、Cookie と併用してステートフルっぽくします。

主な動作としては、ユーザーが特定の動作をして Web サーバーにデータを送信してきたとき(例えば商品を買い物カゴに入れる)に Web サーバー側でセッションIDを発行します。
そしてそのセッションIDを Cookie を利用してブラウザに送信します。
ここでユーザーが一度カートから離れても、再度カートにアクセスした際にセッションIDが残っていれば、続きから買い物を再開できると言うことです。

セッションIDを送信方法は先述した Cookie 以外にも URI への埋め込みやフォームデータに埋め込む方法などがありますが、漏洩の危険性が上がってしまうので、一般的には Cookie に含めて渡す方法が使われます。

ちなみにセッションはファイルや Redis で管理されます。
https://tech-blog.rakus.co.jp/entry/2017/10/17/111828

最後に

今回は Cookie について書いてみました。ちゃんと理解しようとしないと結構迷子になりがちなので、この機会にまとめておいてよかったです。
Web 開発をする上でこの辺りの概念は基礎になるかと思うので、しっかり押さえておきたいですね。

Discussion