사용자의 자격 증명(사용자 이름, 이메일, 비밀번호 등)을 통해 신원을 확인하는 인증은 애플리케이션에서 매우 중요하고 민감한 기능입니다. 이 문서에서는 비밀번호 없이 Auth.js 라이브러리를 사용해 Next.js에서 클라이언트 사이드 인증을 설정하는 방법을 알아보겠습니다. React Hooks와 함수형 컴포넌트를 사용하여 사용자가 GitHub 계정이나 매직 링크를 통해 로그인할 수 있는 앱을 구축할 것입니다. 성공적으로 가입하면 소셜 미디어 계정에서 사용자의 데이터(프로필 사진과 이메일)에 접근할 수 있습니다. 또한 미들웨어를 사용하여 경로를 보호하는 방법도 배울 수 있습니다.
(사이트 https://blog.logrocket.com/auth-js-client-side-authentication-next-js/ 의 내용을 따라하면서 번역한 내용입니다. 번역과정에서 오류가 있을 수 있습니다. 참고 바랍니다. 화면에 대한 캡쳐는 위 사이트에 접속해서 보시는 것을 권장합니다.)
Auth.js란 무엇인가요?
Auth.js는 이전에 NextAuth.js로 알려졌던 보안성과 유연성을 갖춘 인증 라이브러리로, 다양한 OAuth 서비스와 동기화할 수 있으며 비밀번호 없는 로그인도 완벽하게 지원합니다. Auth.js는 데이터베이스와 함께 또는 데이터베이스 없이 사용할 수 있으며, MySQL, MongoDB, PostgreSQL, MariaDB와 같은 인기 있는 데이터베이스를 기본적으로 지원합니다. 데이터베이스 없이도 OAuth와 JSON 웹 토큰(JWT)과 동기화하여 사용할 수 있습니다.
Auth.js의 작동 원리
Auth.js를 사용하면 Next.js 애플리케이션을 보안하기 위해 OAuth를 사용할 때처럼 신원 프로토콜에 대한 전문가가 될 필요가 없습니다. Auth.js는 내장된 자격 증명 제공자를 통해 비밀번호 인증을 지원하지만, 보안상의 위험 때문에 사용자의 비밀번호와 같은 민감한 데이터를 저장하는 것을 강력히 권장하지 않습니다. Auth.js는 애플리케이션에서 세션과 상호작용할 수 있는 클라이언트 사이드 API를 제공합니다. 제공자로부터 반환된 세션 데이터에는 사용자 페이로드가 포함되어 있으며, 성공적인 로그인 후 사용자에게 표시될 수 있습니다.
세션 데이터 예시는 다음과 같습니다:
{
"expires": "2055-12-07T09:56:01.450Z",
"user": {
"email": "sample@example.com",
"image": "https://avatars2.githubusercontent.com/u/45228014?v=4",
"name": "Ejiro Asiuwhu"
}
}
이 페이로드에는 민감한 데이터가 포함되어 있지 않습니다. 세션 페이로드 또는 데이터는 사용자에게 표시하기 위한 목적으로 사용됩니다. Auth.js는 사용자 로그인 상태를 확인할 수 있는 useSession
React Hook도 제공합니다. Auth.js가 제공하는 REST API에 대해 더 알고 싶다면 공식 문서를 참조하세요.
요구 사항
- 로컬 머신에 Node.js 설치
- React와 Next.js 14에 대한 기본적인 이해
Next.js 스타터 애플리케이션 생성
새로운 Next.js 애플리케이션을 생성하려면 다음 명령어를 실행하세요:
npx create-next-app@latest
질문에 대한 응답을 하고 프로젝트 폴더로 이동한 후 개발 서버를 실행합니다:
npm run dev
# 또는
yarn run dev
기본적으로 프로젝트는 포트 3000에서 실행됩니다. 브라우저를 열고 http://localhost:3000
으로 이동하면 시작 페이지를 확인할 수 있습니다.
Auth.js를 사용한 인증 설정
이제 Next.js 스타터 애플리케이션을 준비했으니, Auth.js를 사용해 Next.js 앱을 인증하는 방법을 배워보겠습니다.
Auth.js 설치
Auth.js v5는 현재 베타 버전이므로 다음 명령어를 사용해 설치합니다:
npm install next-auth@beta
# 또는
pnpm add next-auth@beta
Auth.js 구성
Auth.js를 올바르게 설정하려면 구성 파일을 설정하고 인증 흐름을 처리하는 필요한 Auth.js 엔드포인트를 노출해야 합니다. v5에서는 프로젝트의 루트에 auth.ts
파일을 생성하여 구성합니다. src
디렉토리에 auth.ts
파일을 생성하세요:
// ./src/auth.ts
import NextAuth from 'next-auth';
import Github from 'next-auth/providers/github';
import type { NextAuthConfig } from 'next-auth';
export const { handlers, auth } = NextAuth({
providers: [Github],
debug: process.env.NODE_ENV === 'development',
} satisfies NextAuthConfig);
이 코드는 GitHub을 제공자로 사용하여 Auth.js를 구성하고, 개발 중에는 debug
모드를 활성화합니다. 다음으로 모든 관련 Auth.js API 경로에 응답하는 catch-all 동적 라우트를 생성합니다:
// src/app/api/[...nextauth]/route.ts
import { handlers } from '@/auth';
export const { GET, POST } = handlers;
환경 변수 설정
Auth.js는 JWT를 서명하고 검증하며 세션 데이터를 암호화하기 위해 AUTH_SECRET
환경 변수가 필요합니다. 이 값은 길고 무작위로 생성된 문자열이어야 하며 공개적으로 노출되지 않아야 합니다. Node.js 내장 모듈인 crypto
를 사용하거나 OpenSSL 명령어를 사용해 비밀을 생성할 수 있습니다:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
또는
openssl rand -base64 32
생성된 값을 .env.local
파일에 설정하세요:
# .env.local
AUTH_SECRET=<YOUR_SECRET_KEY>
AUTH_GITHUB_ID=<YOUR_GITHUB_ID>
AUTH_GITHUB_SECRET=<YOUR_GITHUB_SECRET>
이제 기본적인 GitHub 인증 설정이 완료되었습니다. http://localhost:3000/api/auth/signin
경로로 이동하면 GitHub 로그인 버튼이 표시됩니다. signIn
함수를 사용해 클라이언트 컴포넌트에서 로그인 프로세스를 수동으로 시작할 수도 있습니다:
"use client";
import { signIn } from 'next-auth/react';
export default function GitHubButton() {
return (
<button onClick={() => signIn('github')}>Continue with GitHub</button>
);
}
사용자 로그인 상태 확인
Auth.js v5에서는 세션 데이터를 확인하기 위해 단일 auth()
호출로 여러 API를 통합했습니다. useSession
Hook을 사용해 사용자의 로그인 상태를 확인하고 세션 정보를 가져올 수 있습니다. 먼저 SessionProvider
를 구성하고 애플리케이션을 감싸도록 설정해야 합니다. layout.tsx
파일을 다음과 같이 업데이트하세요:
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';
import { auth } from '@/auth';
import { SessionProvider } from 'next-auth/react';
const inter = Inter({ subsets: ['latin'] });
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
};
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const session = await auth();
return (
<html lang='en'>
<body className={inter.className}>
<SessionProvider session={session}>
{children}
</SessionProvider>
</body>
</html>
);
}
useSession
Hook 사용
이제 useSession
Hook을 사용해 로그인한 사용자의 정보를 가져와 애플리케이션에 표시할 수 있습니다. UserSession.tsx
파일을 생성하고 다음 코드를 입력하세요:
'use client';
import { useSession, signIn, signOut } from 'next-auth/react';
import { Button } from './ui/button';
export default function UserSession() {
const { data: session } = useSession();
return (
<main className='mt-5 flex justify-center text-white w-[350px] p-3 rounded-md'>
<div className='flex flex-col space-y-4'>
{session ? (
<>
<h2 className='text-xl font-bold'>You're signed in as:</h2>
<pre>{JSON.stringify(session.user?.email)}</pre>
<Button onClick={() => signOut()}>Sign out</Button>
</>
) : (
<Button onClick={() => signIn()}>Sign In</Button>
)}
</div>
</main>
);
}
서버에서 세션 쿼리
서버 환경에서 auth
호출을 사용해 사용자 세션을 쿼리할 수 있습니다:
import { auth } from '@/auth';
export default async function MyServerComponent({
children,
}: {
children: React.ReactNode;
}) {
const session = await auth();
return (
<div>
<p>My email is {session.user?.email}</p>
</div>
);
}
결론
이 문서에서는 Auth.js 라이브러리를 사용해 Next.js 애플리케이션에서 클라이언트 사이드 인증을 설정하는 과정을 다뤘습니다. Auth.js는 다양한 OAuth 제공자와 비밀번호 없는 로그인 방식을 지원하는 보안성과 유
연성을 갖춘 인증 솔루션입니다. 이 가이드를 따르면 Next.js 애플리케이션에 안전한 인증 시스템을 구현할 수 있을 것입니다.