Supabase + Next.jsアプリ開発(3)-認証機能

Supabaseで認証機能を実装してみます。Supabase + Next.jsアプリ開発(1)で紹介した以下のスクリプトでアプリを作ると、デフォルトでauth関係のフォルダとファイルが生成されますので今回はその内容を理解することに注力します。

npx create-next-app -e with-supabase

これでlocalhost:3000にアクセスすると、トップ画面の下方に以下が表示されます。

この指示通り、Supabaseのプロジェクトを作り(作成済みのはず)、環境変数を.env.localにコピペしてリスタートすると、トップページが以下のように変わります。

最初のユーザー登録をしろ、ということですのでやっていきます。supabaseのプロジェクトサイトに行って、SQL Editorで以下を実行しておきます。これでユーザー登録用のテーブルが準備されます。

 select * from auth.users;

localhost:3000/loginにアクセスすると、emailとpasswordでのユーザー登録が求められますので入力してSignUpします。すると登録したメールアドレスに確認メールが届き、confirmするとログイン後のページlocalhost:3000/protectedが開きます。このページにもNext stepsが表示されますが、認証に関わることではないのでここから先は割愛して、ここまでの認証機能がどのように実装されていたのかをみていきたいと思います。ログインページ(app/login/page.tsx)のポイントを説明していきます。

app/login/page.tsx

import Link from "next/link";
import { headers } from "next/headers";
import { createClient } from "@/utils/supabase/server";
import { redirect } from "next/navigation";
import { SubmitButton } from "./submit-button";

export default function Login({
  searchParams,
}: {
  searchParams: { message: string };
}) {
  const signIn = async (formData: FormData) => {
    "use server";

    const email = formData.get("email") as string;
    const password = formData.get("password") as string;
    const supabase = createClient();

    const { error } = await supabase.auth.signInWithPassword({
      email,
      password,
    });

    if (error) {
      return redirect("/login?message=Could not authenticate user");
    }

    return redirect("/protected");
  };

  const signUp = async (formData: FormData) => {
    "use server";

    const origin = headers().get("origin");
    const email = formData.get("email") as string;
    const password = formData.get("password") as string;
    const supabase = createClient();

    const { error } = await supabase.auth.signUp({
      email,
      password,
      options: {
        emailRedirectTo: `${origin}/auth/callback`,
      },
    });

    if (error) {
      return redirect("/login?message=Could not authenticate user");
    }

    return redirect("/login?message=Check email to continue sign in process");
  };

  return (
    <div className="flex-1 flex flex-col w-full px-8 sm:max-w-md justify-center gap-2">
//(中略)
    </div>
  );
}

supabaseの認証機能で用意されている 「supabase.auth.signInWithPassword()」関数と「supabase.auth.signUp()」関数が使用されています。supabase.auth.signUp()ではオプションでemailRedirectTo: でemailアドレスのconfirmを行っています。簡単ですね。