next-auth 이용해서 10분만에 소셜 로그인 구현 하기

반응형

next-auth란?

next-auth는 Next.js 프로젝트에서 소셜 로그인을 간단하게 구현할 수 있는 라이브러리 입니다.
 
국내에서는 구글, 카카오, 네이버, 페이스북, 애플 등 다양한 소셜 로그인을 이용하고 사용합니다.
해당 사이트가 늘어나면 늘어날 수록 로직은 달라지고 복잡해지는데 next-auth를 이용하면 한번에 쉽고 간단하게 구현 가능합니다.
 

Next.js 프로젝트 구성하기

Typescript, tailwind, App Router 방식을 이용해서 구현할 예정입니다.
저는 shacdn이라는 라이브러리를 사용해서 버튼과 아바타 컴포넌트를 사용할 예정입니다.

 

Next.js 설치하기 npx create-next-app

Next.js 설치하는 방법에 대해서 알아보도록 하겠습니다. 설치하는 방법에는 두가지가 있습니다. npx create-next-app을 이용해서 한 번에 자동으로 설치하는 방법과 next.js에 필요한 라이브러리를 하나

powerku.tistory.com

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');

파라미터에 로그인 정보를 입력하게 되면 바로 로그인 화면으로 진행하게 됩니다.

728x90
반응형