🔍

Next.js と Supabaseでサーバーサイド認証を実装する際に気をつけること

2024/09/23に公開

はじめに

Next.js と Supabase でWebアプリケーションのサーバーサイド認証を実装する際に気をつけたい点を記載します。

環境

  • Next.js (App Router)
  • @supabase/ssr

https://supabase.com/docs/guides/auth/server-side/nextjs
公式サイトに書かれているガイドに沿って実装する中で、気をつける点を記載。

Tips

middlewareの設定

課題

Next.js の middleware は、すべてのルートに対して呼び出される。そのため、何もしないと1ページで複数実行されうる。

解決策

静的画像はmiddlewareをパスするように設定
コンポーネントのファイル内に画像を入れていると画像が呼び出される度にmiddlewareが実行されます。
画像系の場合は、次の処理に進ませないで処理を終了させるようにしました。

// middleware.ts
export async function middleware(req: NextRequest) {
  const { pathname } = req.nextUrl;

  // 画像ファイル系は処理をしない
  if (
    pathname.endsWith(".svg") ||
    pathname.endsWith(".ico") ||
    pathname.endsWith(".jpg") ||
    pathname.endsWith(".jpeg") ||
    pathname.endsWith(".png") ||
    pathname.endsWith(".gif")
  ) {
    return NextResponse.next();
  }
    ・・・
}

ログインユーザーの情報は、getSession() ではなく getUser() を使う

ログインユーザーの情報はgetSession()getUser() どちらでも取得可能ですが、getUser() を使うようにします。

理由

getSession() は Cookie からユーザーセッションを取得します。この情報は、送信者によって改ざんされる可能性があります。

getUser() は、ローカルセッションではなくデータベースからユーザーオブジェクトを取得します。このメソッドは、Supabase認証サーバーにリクエストを送信してユーザーのアクセストークンを再検証するため、信頼しても安全です。
https://supabase.com/docs/reference/javascript/auth-getsession

自分のプロジェクトでは次のような関数を用意して利用するようにしています。

async function getUserFromSession(supabaseClient, session) {
  if (!session) return null;
  return supabaseClient.auth.getUser()
}

Discussion