NextAuth: 소셜 로그인 및 세션 처리

next-auth란

next-auth는 다양한 로그인 방식을 제공하는 인증 라이브러리이다. 다양한 소셜 로그인 방식을 제공하며, 이메일/비밀번호 로그인 방식도 제공한다.

공식 문서에는 다음 3가지 특징이 있다고 한다.

설치하기

database로는 무료로 사용가능한 Firebase를 사용했다. next-auth에서는 firebase adapter를 제공하기에 쉽게 개발을 할 수 있다.

소셜 로그인으로는 Google과 Kakao로그인을 사용했다.

  1. next-auth 설치
pnpm install next-auth firebase-admin @auth/firebase-adapter
  1. api 만들기
app/api/auth/[…nextAuth]/route.ts
import { authOptions } from '@/utils';
import NextAuth from 'next-auth/next';

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };
app/utils/authOptions.ts
import { AuthOptions } from 'next-auth';
import { FirestoreAdapter } from '@auth/firebase-adapter';
import { cert } from 'firebase-admin/app';
import { Adapter } from 'next-auth/adapters';
import GoogleProvider from 'next-auth/providers/google';
import KakaoProvider from 'next-auth/providers/kakao';

export const authOptions: AuthOptions = {
  providers: [
    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!,
    }),
  ],
  adapter: FirestoreAdapter({
    credential: cert({
      projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
      clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
      privateKey: process.env.FIREBASE_PRIVATE_KEY!.replace(/\\n/g, '\n'),
    }),
  }) as Adapter,
  callbacks: {
    session({ session, token, user }) {
      session.id = user.id;
      return session;
    },
  },
  secret: process.env.NEXTAUTH_SECRET,
};

오류 error Can't resolve 'net' 절대 경로로 api에 사용되는 next-auth파일을 utils폴더에 넣어서 내보내니 client, server에서 둘다 사용가능한 파일이 되었다. nextjs 에서는 server와 client를 나누어 주어서 authOptions를 내보낼때 client 전용 파일과 같이 내보내면 안된다.

./next-auth.d.ts
import NextAuth from 'next-auth';

declare module 'next-auth' {
  interface Session {
    id: string;
  }
}

next-auth에서 session에 id를 추가하기 위한 타입 선언

  1. 로그인 세션 사용하기
providers.tsx
'use client';
import { Session } from 'next-auth';
import { SessionProvider } from 'next-auth/react';

interface ProvidersProps {
  children: React.ReactNode;
  session?: Session;
}

export function Providers({ children, session }: ProvidersProps) {
  return <SessionProvider session={session}>{children}</SessionProvider>;
}

위 Provider를 루트 레이아웃에 추가하여 사용한다.

  1. 로그인과 로그아웃
loginHanlder.tsx
import { signIn } from 'next-auth/react';

type LoginType = 'google' | 'kakao';

export const loginHandler = (variant: LoginType) => {
  signIn(variant, { callbackUrl: '/' });
};
loginHanlder.tsx
import { signOut } from 'next-auth/react';

// ...생략
reutnr (
  <button onClick={() => signOut()}>로그아웃</button>
)
  1. 세션 처리
  1. Firebase에 저장 되는값 3개의 accounts, sessions, users 컬렉션이 생성된다.



firebase key 발급

[프로젝트 설정] → [서비스 계정] → [새 비공개키 생성] 키 생성시 키를 가지고 있는 json파일을 다운로드 받을 수 있다.

firebase-admin에서 사용하는 다음 키 3개를 얻을 수 있다

소셜 로그인 키 발급

kakao

  1. [내 애플리케이션] → [요약정보] → REST API 키 : KAKAO_CLIENT_ID

  1. [내 애플리케이션] → [보안] → 코드 : KAKAO_CLIENT_SECRET

  1. [내 애플리케이션] → [카카오로그인] → 활성화 ON 및 RedirectURL 등록

  1. [동의항목] *닉네임 및 이미지 등을 받기 위해서는 아래 내용 동의에서 추가할 수 있다

Google

firebase를 사용하면 google 로그인 key를 발급 밥기 쉽다.

  1. 새 제공업체 구글 추가

  1. 웹 SDK 구성에서 구글 로그인 key를 얻을 수 있다

  1. RedirectURL 등록