Supabaseのユーザー認証でエラーが発生したり、認証メールが届かなかったりして、ネットで調べてもわからないことがありました。そんな時の解決方法について説明します。
Next.jsのSupabaseのテンプレートのコードをコピペするのがおすすめ
「エラーを解消できない」「認証メールが届かない」「SSR, Client, Serverでのコードの書き分けがわからない」という方は、Next.jsのテンプレートSupabase Starterのコードをコピペするのがおすすめです。
上記のテンプレートは、Next.js 14、SSRに対応しています。これを参考にすれば、Supabaseのユーザー認証に関するエラーは大体解決すると思います。
ソースコード
一部抜粋。
/utils/supabase/server.ts
import { createServerClient, type CookieOptions } from '@supabase/ssr' import { cookies } from 'next/headers' export const createClient = (cookieStore: ReturnType<typeof cookies>) => { return createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { cookies: { get(name: string) { return cookieStore.get(name)?.value }, set(name: string, value: string, options: CookieOptions) { try { cookieStore.set({ name, value, ...options }) } catch (error) { // The `set` method was called from a Server Component. // This can be ignored if you have middleware refreshing // user sessions. } }, remove(name: string, options: CookieOptions) { try { cookieStore.set({ name, value: '', ...options }) } catch (error) { // The `delete` method was called from a Server Component. // This can be ignored if you have middleware refreshing // user sessions. } }, }, } ) }
/app/login/page.tsx
import Link from 'next/link' import { headers, cookies } from 'next/headers' import { createClient } from '@/utils/supabase/server' import { redirect } from 'next/navigation' 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 cookieStore = cookies() const supabase = createClient(cookieStore) const { error } = await supabase.auth.signInWithPassword({ email, password, }) if (error) { return redirect('/login?message=Could not authenticate user') } return redirect('/') } 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 cookieStore = cookies() const supabase = createClient(cookieStore) 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 ( // 省略 ) }