본문 바로가기
Frontend

[Next.js 14] NextAuth 적용기 (네이버 로그인, 카카오 로그인, 구글 로그인)

by 태균맨 2025. 4. 17.

프로젝트 고도화를 하면서 미루고 미뤄왔던 SNS 로그인 연동을 할 시간이 왔습니다.
 

무늬만 있던 SNS 로그인 버튼들

 
 

✅ 기존 로그인 로직

1. 사용자 입력 정보를 암호화하여 api요청
2. 복호화 하여 DB 조회
3. JWT 토큰 발급 및 쿠키 저장
4. 응답을 암호화해서 반환
5. Zustand로 로그인 상태 관리

 
 
내가 구현하고 싶은 로직은 이랬다.

  • 리다이렉트를 최소화 해서 로그인
  • 어떤 페이지에서도 로그인 가능
  • SNS 아이디 연동이 안되어 있으면 바로 회원가입
  • 회원가입 후 바로 로그인

 

이전에 연동할 땐 바닐라 JS와 리다이렉션을 이용해서 연동 해뒀었는데
next.js에서 NextAuth라는 라이브러리를 적용해보았다.

✅ NextAuth

Next.js에 특화된 인증 라이브러리

다양한 로그인 지원
👉 Google, Kakao, Naver 같은 OAuth부터 ID/비밀번호 로그인까지 모두 가능
간편한 클라이언트/서버 통합
👉 useSession, signIn, signOut 훅으로 클라이언트 인증 상태 쉽게 관리
JWT 세션/쿠키 자동 관리
👉 JWT 토큰 발급, 쿠키 저장, 보안 설정까지 자동 처리
서버사이드 렌더링(SSR) 지원
👉 getServerSession으로 서버에서도 인증 상태 안전하게 사용 가능
확장성 높은 커스텀
👉 로그인, 세션, 리다이렉트 시 커스텀 콜백 함수 제공
보안성
👉 OAuth 2.0 표준, HttpOnly 쿠키, JWT 암호화로 안전한 인증

..라고 합니다

 
오늘 처음 적용해본 거라 깊게는 못 해보고 실속 있게 구현했습니다.
 
 

npm install next-auth

바로 설치해보았습니다!
 

1. /api/auth/[...nextauth]/route.ts 파일을 만들어 줘야합니다.

요런식으로

 

저는 .env에 미리 추가해두었습니다.

 
 

// src/app/api/auth/[...nextauth]/route.ts


import NextAuth from "next-auth";
import NaverProvider from "next-auth/providers/naver";
import KakaoProvider from "next-auth/providers/kakao";
import GoogleProvider from "next-auth/providers/google";


const handler = NextAuth({
  providers: [
    NaverProvider({
      clientId: process.env.NAVER_CLIENT_ID!,
      clientSecret: process.env.NAVER_CLIENT_SECRET!,
    }),
    KakaoProvider({
      clientId: process.env.KAKAO_CLIENT_ID!,
      clientSecret: process.env.KAKAO_CLIENT_SECRET!,
    }),
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
})

export { handler as GET, handler as POST }

 

네이버/카카오/구글 providers를 추가해줍시다.

http://localhost:3000/api/auth/signin 로 가서 확인해보면 친절한 라이브러리가 로그인을 다 연동해놓았다.

 
 

2. Context를 만들어서 SessionProvider로 감싸주기

"use client";

import { SessionProvider } from "next-auth/react";

interface Props {
  children: React.ReactNode;
}

const NextAuthProvider = ({ children }: Props) => {
  return <SessionProvider>{children}</SessionProvider>;
};

export default NextAuthProvider;

Context 만들어주고

 

// app/layout.tsx

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ko"}>
      <body className={pretendard.className}>
        <NextAuthProvider>{children}</NextAuthProvider>
      </body>
    </html>
  );
}

레이아웃에 이렇게 감싸주시면 됩니다.
(use client 사용해야 돼서)

 
이제 NextAuth의 useSession 훅을 사용해 세션 정보를 받아 올 수 있다.

3. 준비는 끝났으니 테스트를 해보자.

http://localhost:3000/api/auth/signin 에서도 테스트 할 수 있고,
함수로 저 동작을 호출할 수도 있다.

import { signIn } from "next-auth/react";


   signIn('naver', {
      redirect: true,
      callbackUrl: "/",
    });

외부에서 호출하려면 이런 식으로 사용하면 된다.

너무 간편...

 
 
 
 

import NextAuth from "next-auth";
import NaverProvider from "next-auth/providers/naver";
import KakaoProvider from "next-auth/providers/kakao";
import GoogleProvider from "next-auth/providers/google";

const handler = NextAuth({
  providers: [
    NaverProvider({
      clientId: process.env.NAVER_CLIENT_ID!,
      clientSecret: process.env.NAVER_CLIENT_SECRET!,
    }),
    KakaoProvider({
      clientId: process.env.KAKAO_CLIENT_ID!,
      clientSecret: process.env.KAKAO_CLIENT_SECRET!,
    }),
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
  callbacks: {
    async signIn({ user, account, profile }) {
      console.log("user", user);
      console.log("account", account);
      console.log("profile", profile);

      return true;
    },
  },
});

export { handler as GET, handler as POST };

api에서는 대충.. 이렇게 사용했습니다.

 

import { useSession } from "next-auth/react";

  
  ...
  
    const { data: SnsSession } = useSession();
    
    console.log("session",SnsSession)

 

클라이언트에서는 이런식으로..

 
 
 

로그인에 성공하면 useSession 으로도 확인 가능하고 (client)
api의 callbacks 옵션 으로도 확인 가능합니다. (api)
상황에 맞게 로직을 구현해주시면 됩니다.

 
 
저는 미리 만들어둔 Dialog 모달을 이용해 로그인을 연동했습니다.
 
(팝업창을 띄워서 로그인 성공하면 세션을 받아오고 useEffect로 세션을 체크해 로그인하는 방식 (?))
 
 

 

 
 
저는 useSession 훅의 status도 사용해서 로딩도 구현해줬습니다.
 
 
아 참. 로그아웃은 더 간단합니다.
 

import { signOut } from "next-auth/react";

signOut({ 
redirect: false, 
// callbackUrl: "/" // 필요 시 설정
});

이러면 세션이 날라갑니다.
 

정리

SNS 연동이 너무 간단해졌다.
 
다음에 제대로 봐야지~