next-auth란?
next-auth는 Next.js 프로젝트에서 소셜 로그인을 간단하게 구현할 수 있는 라이브러리 입니다.
국내에서는 구글, 카카오, 네이버, 페이스북, 애플 등 다양한 소셜 로그인을 이용하고 사용합니다.
해당 사이트가 늘어나면 늘어날 수록 로직은 달라지고 복잡해지는데 next-auth를 이용하면 한번에 쉽고 간단하게 구현 가능합니다.
Next.js 프로젝트 구성하기
Typescript, tailwind, App Router 방식을 이용해서 구현할 예정입니다.
저는 shacdn이라는 라이브러리를 사용해서 버튼과 아바타 컴포넌트를 사용할 예정입니다.
next-auth 설치하기
npm install next-auth
API Route 추가하기
app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth";
import KakaoProvider from "next-auth/providers/kakao";
import NaverProvider from "next-auth/providers/naver";
import GoogleProvider from "next-auth/providers/google";
export const authOptions = {
// Configure one or more authentication providers
providers: [
KakaoProvider({
clientId: process.env.KAKAO_CLIENT_ID ?? "",
clientSecret: process.env.KAKAO_CLIENT_SECRET ?? "",
}),
NaverProvider({
clientId: process.env.KAKAO_CLIENT_ID ?? "",
clientSecret: process.env.KAKAO_CLIENT_SECRET ?? "",
}),
GoogleProvider({
clientId: process.env.KAKAO_CLIENT_ID ?? "",
clientSecret: process.env.KAKAO_CLIENT_SECRET ?? "",
}),
// ...add more providers here
],
};
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
.env
KAKAO_CLIENT_ID="YOUR_CLIENT_ID"
KAKAO_CLIENT_SECRET="YOUR_SECERT_ID"
Session Provider 감싸주기
components/providers/session-provider.tsx
"use client";
import { SessionProvider } from "next-auth/react";
import { ReactNode } from "react";
import { Session } from "next-auth";
type Props = {
session?: Session | null;
children: ReactNode;
};
export default function AuthSession({ session, children }: Props) {
return <SessionProvider session={session}>{children}</SessionProvider>;
}
app/layout.tsx
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'
import AuthSession from '@/components/providers/session-provider'
import LoginButton from '@/components/login-button'
const inter = Inter({ subsets: ['latin'] })
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={inter.className}>
<AuthSession>
<div className="h-[48px] bg-black flex items-center">
<ul className="ml-auto mr-5">
<li><LoginButton></LoginButton></li>
</ul>
</div>
{children}
</AuthSession>
</body>
</html>
)
}
로그인 버튼 구현하기
components/login-button.tsx
"use client";
import {signIn, signOut, useSession } from 'next-auth/react';
import React from 'react';
import {Avatar, AvatarFallback, AvatarImage} from "@/components/ui/avatar";
const LoginButton = () => {
const {data} = useSession();
const onClick = async (e: React.MouseEvent) => {
e.preventDefault();
if (data) {
await signOut();
} else {
await signIn();
}
}
return (
<div className="flex items-center gap-3">
{data?.user && <Avatar>
<AvatarImage src={data.user.image ?? ""} alt="user image" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
}
<a href="#" onClick={onClick} className="text-sm text-white">{data ? "로그아웃": "카카오 아이디로 로그인"}</a>
</div>
);
};
export default LoginButton;
결과 화면
우측 상단 로그인 버튼을 클릭하면 로그인 화면으로 이동하게 되고, 소셜 로그인 창에서 로그인이 가능합니다.
아쉽지만, 카카오와 네이버는 아이콘이 없습니다.
세션 정보 가져오기
클라이언트 컴포넌트 ▶️ useSession
로그인 완료 이후에는 useSession API를 통해 로그인 정보를 가지고 올 수 있습니다.
로그인 정보에는 이름, image, email 등이 있습니다.
const { data } = useSession();
서버 컴포넌트 또는 API ▶️ getServerSession
import {authOptions} from "@/app/api/auth/[...nextauth]/route";
const session = await getServerSession(authOptions);
로그인 / 로그 아웃
로그인, 로그아웃시에 signIn, signOut API를 통해서 가능합니다.
signIn
파라미터가 없을 경우, 소셜 로그인 선택하는 화면으로 이동하게 되고,
signIn('kakako');
파라미터에 로그인 정보를 입력하게 되면 바로 로그인 화면으로 진행하게 됩니다.