🍆

【Supabase】middleware.tsで取得したデータをlayout.tsxやpage.tsxなど各ページに渡したい

2024/12/06に公開

Supabaseの公式ドキュメントでは、サーバーサイドでの認証の例として、 middleware.ts および utils/supabase/middleware.ts でセッションを更新する記述が掲載されています。

▼下記の記事▼
https://supabase.com/docs/guides/auth/server-side/nextjs?queryGroups=router&router=app

utils/supabase/middleware.ts では、

const {
  data: { user },
} = await supabase.auth.getUser()

でユーザー情報を取得しています。
この取得結果の認証状況に応じて、リダイレクトしてページアクセス制限を実現できる訳ですが、どうせなら middleware で取得したデータを他の layout.tsx や page.tsx で使いたいですよね?

各種ページで再度 await supabase.auth.getUser() を呼び出すのはリクエスト数が無駄に増えてしまうため避けたいところです。

ということで、本記事では、 middleware.ts のデータを layout.tsx や page.tsx でも使えるようにする方法を紹介します。

元ネタ

https://x.com/gadingnstn/status/1702625163454656690

middleware.ts で supabaseResponse.headers に値をセットする

layout.tsx や page.tsx に渡したいデータを

supabaseResponse.headers.set("x-hoge", "ここにデータ") という形でセットするだけです。

セットした値を呼び出す

layouts.tsxやpage.tsxで、

import { headers } from "next/headers";

...const headersList = await headers();
  const searchParams = headersList.get("x-hoge") as string;
  console.log(searchParams);

このように書いてみましょう。
該当ページをブラウザで開くと、ターミナル上にセットした値が取得できていることが確認できます。

おしまい

管理が面倒なことになりそうですが、余計なリクエストを増やすことなく認証結果を渡せるメリットは大きいと思います。ただし、セキュリティ的な問題がありそうなので、ユーザー名、ユーザー画像など、それほど大きな問題にならない要素だけの利用に留めておく方が懸命でしょう。

Discussion