カルボナーラ街道

計測と観察

GoでCookieを使ってみる

本記事は下記を参考にしています。

developer.mozilla.org


自作GraphQLサーバーを公開しようと思ったら、認証について何もやっていないことに気がついた。
認証について調べるとCookieやJWTというワードがちらついたが、今回は名前だけは聞いたことがあるCookieをGoでどう設定するか見ていく。

開発環境

github.com

# ホスト
> docker --version
Docker version 20.10.8, build 3967b7d

> docker-compose --version
docker-compose version 1.29.2, build 5becea4c

# コンテナ
/go/src # go version
go version go1.17.8 linux/amd64
/go/src # 

# Chrome
バージョン: 99.0.4844.51(Official Build) (x86_64)

Cookie とは

サーバーがユーザーのウェブブラウザーに送信する小さなデータであり、ブラウザーに保存され、その後のリクエストと共に同じサーバーへ返送されます。一般的には、二つのリクエストが同じブラウザーから送信されたものであるかを知るために使用されます。
https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies

用途は主にセッション管理、パーソナライゼーション、トラッキングで使われる。
今回はセッション管理が認証に該当しそうなので、セッション管理について見ていく。

Cookieの作成

HTTP リクエストを受け取った後、サーバーはレスポンスで Set-Cookie ヘッダーを送信することができます。
https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies

現状のレスポンスヘッダーを見てみる。

> curl --dump-header - \
> -H 'Content-Type:application/json' \
> -X POST -d '{ idols(age: 20) { name height} }' \
> 'http://localhost:8080/graphql'
HTTP/1.1 200 OK
Access-Control-Allow-Headers: *  # サーバー側で設定した
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS  # サーバー側で設定した
Access-Control-Allow-Origin: *  # サーバー側で設定した
Date: Fri, 11 Mar 2022 06:13:10 GMT
Content-Length: 99
Content-Type: text/plain; charset=utf-8

{"data":{"idols":[{"height":168,"name":"有栖川 夏葉"},{"height":161,"name":"斑鳩 ルカ"}]}}%  

デフォルトではSet-Cookieヘッダーは無いようだ。

レスポンスヘッダーにSet-Cookieを付与する

http.HandleFunc("/graphql", func(rw http.ResponseWriter, r *http.Request) {
        // ...
        cookie := http.Cookie{
            Name:  "cookie_name",
            Value: "cookie_value",
        }
        http.SetCookie(rw, &cookie)
        // ...
})

> curl --dump-header - \
-H 'Content-Type:application/json' \
-X POST -d '{ idols(age: 21) { name height} }' \
'http://localhost:8080/graphql'
HTTP/1.1 200 OK
# ...
Set-Cookie: cookie_name=cookie_value  # 追加されてる
# ...

レスポンスヘッダーにSet-Cookieが追加されていることが分かる。

ブラウザでも見てみる。 本記事の # 開発環境 に記載のリポジトリの構成は以下。

f:id:tokizuoh:20220311231247p:plain

http://localhost:8081/playground にアクセスして、ChromeCookieを見る。

f:id:tokizuoh:20220311231418p:plain

Goコード内で指定した設定値が入っている。

参考