페이지 2: Next.js (App Router)에서 사용자 인증 구현

2. Next.js (App Router)에서 사용자 인증 구현

Supabase Auth는 강력하고 구현하기 쉬운 인증 시스템을 제공합니다. 이 섹션에서는 Next.js (App Router) 애플리케이션 내에서 이메일/비밀번호 인증을 설정하고 사용자 세션을 관리하는 방법을 다룹니다.

2.1. 사용자 세션을 가져오는 서버 컴포넌트

App Router에서 서버 컴포넌트에서 사용자 세션에 액세스해야 하는 경우가 많습니다. 다음 예시는 세션을 가져오는 방법을 보여줍니다.

// app/page.tsx (또는 모든 서버 컴포넌트)
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'

export default async function Page() {
  const supabase = createClient()

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

  if (!user) {
    redirect('/login') // 사용자가 없으면 로그인으로 리디렉션
  }

  return (
    <div>
      <h1>환영합니다, {user.email}</h1>
      {/* 보호된 콘텐츠 */}
    </div>
  )
}

2.2. 로그인 및 회원가입 클라이언트 컴포넌트

사용자 인증을 위한 클라이언트 컴포넌트를 생성합니다 (예: app/login/page.tsx). 일반적으로 폼을 사용합니다.

'use client'

import { createClient } from '@/lib/supabase/client'
import { useRouter } from 'next/navigation'
import { useState } from 'react'

export default function LoginPage() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const router = useRouter()
  const supabase = createClient()

  const handleSignIn = async (e: React.FormEvent) => {
    e.preventDefault()
    const { error } = await supabase.auth.signInWithPassword({
      email,
      password,
    })

    if (error) {
      alert(error.message)
    } else {
      router.push('/') // 로그인 성공 시 홈 페이지로 리디렉션
    }
  }

  const handleSignUp = async (e: React.FormEvent) => {
    e.preventDefault()
    const { error } = await supabase.auth.signUp({
      email,
      password,
    })

    if (error) {
      alert(error.message)
    } else {
      alert('확인 이메일을 확인해주세요!')
    }
  }

  return (
    <form>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="이메일"
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="비밀번호"
      />
      <button onClick={handleSignIn}>로그인</button>
      <button onClick={handleSignUp}>회원가입</button>
    </form>
  )
}

중요: 이 컴포넌트를 호스팅하기 위해 App Router에 /login 경로를 설정하는 것을 잊지 마세요.

2.3. 사용자 세션 관리

@supabase/ssr 패키지는 쿠키를 사용하여 사용자 세션을 자동으로 관리하는 데 도움을 줍니다. 사용자가 로그인하면 Supabase는 안전한 HTTP 전용 쿠키를 설정합니다. 그러면 서버 컴포넌트는 createServerClient를 사용하여 이러한 쿠키를 읽어 수동 토큰 관리 없이 사용자의 인증 상태를 확인할 수 있습니다.

클라이언트 컴포넌트에서 인증 상태 변경을 수신할 수도 있습니다:

supabase.auth.onAuthStateChange((event, session) => {
  if (event === 'SIGNED_IN') {
    // 사용자 로그인됨
  } else if (event === 'SIGNED_OUT') {
    // 사용자 로그아웃됨
  }
})

이 설정은 Next.js 애플리케이션을 위한 완전한 인증 흐름을 제공합니다.