2024-06-02

Next.js で Cluod CDN の署名付き Cookie を使用するときにつまづいたこと

署名付き Cookie を設定して Cloud Storage の静的ファイルを配信するため、Next.js でエンコードせずに Cookie を設定する方法を調べて、最終的に Cookie 生成 API を立てた。

やりたいこと

特定のページにアクセスした際、署名付き Cookie を設定して Cloud Storage にある静的ファイルを配信する。

署名付き Cookie を使用する  |  Cloud CDN  |  Google Cloud

最終的にやったこと: Cookie 生成 API を作る。

つまづいたこと

Cookie の値がエンコードされる

Next.js では cookies().set(name, '') で Cookie を設定できる。この際、値は encodeURIComponent でエンコードされる。

Functions: cookies | Next.js

Cloud CDN で使用する署名付き Cookie には = が含まれているため、この方法で設定した Cookie では検証に失敗する。そこで、エンコードせずに Cookie を設定しなければならない。

CookieSerializeOptions には encode といういかにもなオプションがあるが、定義されているだけで使えない。

NextApiResponse.headers.setSet-Cookie ヘッダに直接値を設定することでエンコードを避けられる。

Server Actions でエンコードしない Cookie を設定できない

Server Actions では、 cookies()は使えるがレスポンスヘッダーに直接値を設定できない。

middleware に _rscリクエストが飛んでCookieが書き換わってしまう

これは Cookie の問題ではないが見落としていたポイント。

特定のページへアクセスしたときに middleware で Cookie を設定する実装にしていた。Cookie 自体は正しく設定できていたが、特定の要素をスクロールすると Cookie がどんどん書き換わる現象が起こった。

原因は Link タグの prefetch だった。Link タグがスクロールによってユーザーのビューポートに入ると、リンク先にリクエストが送信され、そのたびに middleware で Cookie を書き換える処理が走っていた。

Components: | Next.js

最終的にやったこと: Cookie生成APIを叩く

Cookie を設定する API を作り、ページにアクセスしたときに API を叩いて Cookie を設定するようにした。