icon안동민 개발노트

로그인 및 로그아웃 구현


 NextAuth.js를 사용하여 로그인 및 로그아웃 기능을 구현하는 방법을 살펴보겠습니다.

 이 절에서는 로그인 폼 생성, 세션 상태에 따른 UI 렌더링, 로그아웃 처리, 그리고 보호된 라우트 구현 방법을 다룹니다.

로그인 폼 생성

 NextAuth.js는 기본적인 로그인 페이지를 제공하지만, 커스텀 로그인 폼을 만들어 사용할 수 있습니다. 다음은 간단한 로그인 폼의 예시입니다.

'use client'
 
import { signIn } from 'next-auth/react'
import { useState } from 'react'
 
export default function LoginForm() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
 
  const handleSubmit = async (e) => {
    e.preventDefault()
    const result = await signIn('credentials', {
      redirect: false,
      email,
      password,
    })
    if (result.error) {
      // 에러 처리
    } else {
      // 로그인 성공 처리
    }
  }
 
  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
        required
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="Password"
        required
      />
      <button type="submit">Log in</button>
    </form>
  )
}

 이 폼은 signIn 함수를 사용하여 인증을 처리합니다. 'credentials'는 사용자 정의 자격 증명 제공자를 나타냅니다.

세션 상태에 따른 UI 렌더링

 사용자의 로그인 상태에 따라 다른 UI를 렌더링하려면 useSession 훅을 사용합니다.

'use client'
 
import { useSession } from 'next-auth/react'
 
export default function Header() {
  const { data: session, status } = useSession()
 
  if (status === 'loading') {
    return <div>Loading...</div>
  }
 
  if (session) {
    return <div>Welcome, {session.user.name}!</div>
  }
 
  return <div>Please log in</div>
}

로그아웃 처리

 로그아웃은 signOut 함수를 사용하여 간단히 처리할 수 있습니다.

'use client'
 
import { signOut } from 'next-auth/react'
 
export default function LogoutButton() {
  return <button onClick={() => signOut()}>Log out</button>
}

보호된 라우트 구현

 특정 페이지나 컴포넌트를 인증된 사용자만 접근할 수 있도록 만들려면, 다음과 같은 고차 컴포넌트(HOC)를 사용할 수 있습니다.

'use client'
 
import { useSession } from 'next-auth/react'
import { useRouter } from 'next/navigation'
 
export function withAuth(Component) {
  return function ProtectedRoute(props) {
    const { data: session, status } = useSession()
    const router = useRouter()
 
    if (status === 'loading') {
      return <div>Loading...</div>
    }
 
    if (!session) {
      router.push('/login')
      return null
    }
 
    return <Component {...props} />
  }
}

 이 HOC를 사용하여 보호된 컴포넌트를 만들 수 있습니다.

const ProtectedPage = withAuth(function Page() {
  return <div>This is a protected page</div>
})

8장 상태 관리 및 폼 처리와의 연관성

 NextAuth.js를 사용한 인증 구현은 8장에서 다룬 상태 관리 및 폼 처리와 밀접하게 연관됩니다. 로그인 폼은 React의 상태 관리를 사용하여 구현되며, 폼 제출 시 서버 액션을 통해 처리될 수 있습니다. 또한, 전역 상태 관리 도구(예 : Redux, Zustand)를 사용하여 인증 상태를 관리하고 애플리케이션 전체에서 공유할 수 있습니다.

실습 : 로그인 상태에 따른 내비게이션 바 구현

 다음 요구사항을 만족하는 내비게이션 바를 구현해보세여.

  1. 로그인하지 않은 상태에서는 "Home", "Login" 링크를 표시
  2. 로그인한 상태에서는 "Home", "Profile", "Logout" 링크를 표시
  3. 현재 사용자의 이름을 내비게이션 바에 표시

 구현 예시

'use client'
 
import Link from 'next/link'
import { useSession, signOut } from 'next-auth/react'
 
export default function Navbar() {
  const { data: session, status } = useSession()
 
  return (
    <nav>
      <Link href="/">Home</Link>
      {status === 'authenticated' ? (
        <>
          <Link href="/profile">Profile</Link>
          <button onClick={() => signOut()}>Logout</button>
          <span>Welcome, {session.user.name}!</span>
        </>
      ) : (
        <Link href="/login">Login</Link>
      )}
    </nav>
  )
}

 이 실습을 통해 NextAuth.js의 세션 관리 기능을 활용하여 동적으로 UI를 변경하는 방법을 익힐 수 있습니다. 이는 실제 애플리케이션에서 자주 사용되는 패턴으로, 사용자 경험을 향상시키는 중요한 요소입니다.

 NextAuth.js를 사용한 로그인 및 로그아웃 구현은 웹 애플리케이션의 핵심 기능 중 하나입니다. 이를 통해 사용자 인증을 효과적으로 관리하고, 보안된 사용자 경험을 제공할 수 있습니다. 앞으로의 개발 과정에서 이러한 기술을 활용하여 더욱 강력하고 안전한 애플리케이션을 구축하시기 바랍니다.