코드노트

Next.js 13 OAuth(소셜 로그인) 사용방법 정리, feat.Google/Kakao / Naver 본문

Code note

Next.js 13 OAuth(소셜 로그인) 사용방법 정리, feat.Google/Kakao / Naver

코드노트 2023. 7. 24. 00:43

이번 개인프로젝트에서 OAuth 소셜 로그인을 등록하면서 구글, 카카오, 네이버를 모두 연결하였는데

Next.js 에서 사용할 수 있는 방법을 정리해 놓으려고 한다.

Next.js 13 버전을 사용하고 있기 때문에 NextAuth.js 에서 자세하게 설명이 되어있다.

 

사용방법은 어렵지 않다.

13버전에서 이제는 app 폴더에서 사용할 수 있다.

 

Initialization | NextAuth.js

The main entry point of NextAuth.js is the NextAuth method that you import from next-auth. It handles different types of requests, as defined in the REST API section.

next-auth.js.org

 

13버전 이후 초기에는 page루트로 따로 설정해서 사용했어야 했는데 13.2버전부터 app으로 할 수 있다!

여기서 알고 넘어가야하는점

- 아직은 app 디렉토리에서 적용할때 문제가 발생하는 경우가 있다.

- 일부 사용자는 코드를 실행할때 내보내기 오류가 발생하였고, 이를 해결하기 위해서 NextAuth를 따로 정의하고 내보내어 getServerSession에 authOptions을 연결해주는 방법도 같이 정리하고자 한다.


API 경로 처리, 연결

/app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import KakaoProvider from "next-auth/providers/kakao";
import NaverProvider from "next-auth/providers/naver";

const handler = NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_OAUTH_ID || "",
      clientSecret: process.env.GOOGLE_OAUTH_SECRET || "",
    }),
    KakaoProvider({
      clientId: process.env.KAKAO_CLIENT_ID || "",
      clientSecret: process.env.KAKAO_CLIENT_SECRET || "",
    }),
    NaverProvider({
      clientId: process.env.NAVER_CLIENT_ID || "",
      clientSecret: process.env.NAVER_CLIENT_SECRET || "",
    }),
  ],
});

export { handler as GET, handler as POST };

- 사용방법은 12버전과 크게 다르지 않다. handler에서 NextAuth 안에 providers 배열을 넣어주면 된다.

- 13.2버전에서는 Route Handlers를 도입했다고 한다. NextAuth.js는 내부적으로 Request, Response 인스턴스를 반환한다.

- NextAuth.js가 제대로 작동하려면 GET, POST 처리기가 필요하므로 export 처리를 해주어야 한다.

- 여기서 필요한 구글, 카카오, 네이버의 clientId, Secret key값을 가지고 오는 방법은 아래에 정리하였다.


Provider

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

type Props = {
  children: React.ReactNode;
};

export default function AuthContext({ children }: Props) {
  return <SessionProvider>{children}</SessionProvider>;
}

- next는 Context를 지원한다. 그러나 서버컴포넌트에서는 직접적으로 접근할 수 없다.

- 왜 감싸야할까? SessionProvider를 사용하려면 클라이언트로 사용하여야한다. 우리가 layout에서는 ssr을 사용하기 때문에 이렇게 감싸서 사용하자!

 

import AuthContext from "@/context/AuthContext";

const openSans = Open_Sans({ subsets: ["latin"] });

export const metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" className={openSans.className}>
      <body className="w-full max-w-screen-xl mx-auto overflow-auto ">
        <AuthContext>
          <header className="sticky top-0 z-10 bg-white border-b">
            <Navbar />
          </header>
          <main>{children}</main>
        </AuthContext>
      </body>
    </html>
  );
}

- 그리고 우리는 RootLayout에 감싸주면 끝!

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

  const pathName = usePathname();
  const { data: session } = useSession();

// 구글
{session ? (
  <li>
    <ColorButton text="Sign out" onClick={() => signOut()} />
  </li>
    ) : (
  <li>
    <ColorButton text="Sign in" onClick={() => signIn("google")} />
  </li>
)}
// 카카오
{session ? (
  <li>
    <ColorButton text="Sign out" onClick={() => signOut()} />
  </li>
    ) : (
  <li>
    <ColorButton text="Sign in" onClick={() => signIn("kakao")} />
  </li>
)}
// 네이버
{session ? (
  <li>
    <ColorButton text="Sign out" onClick={() => signOut()} />
  </li>
    ) : (
  <li>
    <ColorButton text="Sign in" onClick={() => signIn("naver")} />
  </li>
)}

- useSession, signIn, signOut을 가지고와서 설정해주어야한다. 콜백함수를 통해서 onclick으로 문자값으로 google, kakao, naver를 전달해주면 해당되는 OAuth가 연결된다. 

 

 

GOOGLE_OAUTH_ID=
GOOGLE_OAUTH_SECRET=
KAKAO_CLIENT_ID=
KAKAO_CLIENT_SECRET=
NAVER_CLIENT_ID=
NAVER_CLIENT_SECRET=

이제 아래에서 필요한 key를 가지고와서 env로 설정해주면 된다.

 

 


lib/auth.ts 를 사용하여 NextAuth 옵션 정의후 내보내기

/src/lib/auth.ts

import { NextAuthOptions } from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import KakaoProvider from "next-auth/providers/kakao";
import NaverProvider from "next-auth/providers/naver";

export const authOptions: NextAuthOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_OAUTH_ID || "",
      clientSecret: process.env.GOOGLE_OAUTH_SECRET || "",
    }),
    KakaoProvider({
      clientId: process.env.KAKAO_CLIENT_ID || "",
      clientSecret: process.env.KAKAO_CLIENT_SECRET || "",
    }),
    NaverProvider({
      clientId: process.env.NAVER_CLIENT_ID || "",
      clientSecret: process.env.NAVER_CLIENT_SECRET || "",
    }),
  ],
  pages: {
    signIn: "/auth/signIn",
  },
};

- 이렇게 auth.ts를 따로 만들어서 authOptions을 따로 정의하고 내보내기를 해준다.

 

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

import { authOptions } from "@/lib/auth";
import NextAuth from "next-auth";

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };

- 그리고 route.ts에 연결할때 NextAuth안에 authOptions을 연결해주는 방법을 사용할 수 있다.

- 이방법을 사용한 이유는 세션 데이터를 획득하기 위함인데 getServerSession을 사용하게 되면 authOptions값을 전달해주어야한다.

- NextAuth로 바로 정의해버리면 authOptions값을 따로 관리할 수 없기 때문에 이렇게 auth.ts에서 options을 빼서 정의 후 사용했다.

만약 다른방법이 있다면 댓글로 가르쳐주세요..

 


구글-OAuth API

 

Google 클라우드 플랫폼

로그인 Google 클라우드 플랫폼으로 이동

accounts.google.com

- 구글클라우드 로고 옆을 클릭하여 새로운 프로젝트를 생성해준다.

 

 

- 이름을 생성하고 조직은 없으면 없다고 해도 된다.

- 시간이 조금 소요되며 바로 생성이 된다.

 

 

- 프로젝트가 생성되면 이렇게 OAuth동의화면에서 내부, 외부를 선택할 수 있는데 구글 내부가 아닌 외부를 선택한다.

 

 

- 앱이름과 사용자 지원 이메일을 작성한다. 승인된 도메인은 배포 후 배포된 도메인을 작성하면 된다.

- 개발자 연락처 정보에 내 이메일을 작성한다. 

 

 

- 이건 지정한 도메인에서만 범위를 설정할 수 있는데 우선 생략! 테스트 사용자도 우선 생략

 

 

- 모든 단계가 완료되었으면 사용자 인증 정보에서 OAuth 클라이언트 ID를 클릭

- 웹 애플리케이션을 클릭!

 

 

- 여기서는 웹 이름과 승인된 자브스크립트 원본에서는 현재 개발 환경이기 때문에 local주소를 입력

 

- Redirect URI에서는 http://localhost:3000/api/auth/callback/google 을 입력해준다.

 

- client ID와, 보안비밀번호를 google key로 사용!


 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

카카오 - OAuth API

 

- kakao developers에 들어가서 애플리케이션을 추가한다.

 

- 내 애플리케이션 > 앱설정 > 요약정보 에서 REST API키를 저장한다.

 

 

- 내 애플리케이션 > 제품설정 > 카카오로그인 > 보안 에서 Client Secret 토큰을 생성하고 저장한다.

 

 

- 내 애플리케이션 > 제품 설정 > 카카오 로그인

- Redirect URI를 연결해주자! 다른 소셜로그인도 마찬가지로 리다이렉트 URI를 연결하지 않으면 에러가 발생한다.

http://localhost:3000/api/auth/callback/kakao

- 만약 배포 후 도메인이 생긴다면 그때 다시 변경해주자!

 

- 내 애플리케이션 > 제품설정 > 카카오 로그인 에서 활성화 설정을 ON으로 한다.


 

 

NAVER Developers

네이버 오픈 API들을 활용해 개발자들이 다양한 애플리케이션을 개발할 수 있도록 API 가이드와 SDK를 제공합니다. 제공중인 오픈 API에는 네이버 로그인, 검색, 단축URL, 캡차를 비롯 기계번역, 음

developers.naver.com

네이버 - OAuth API

- 회원가입 후에 애플리케이션을 등록해주면 된다. 이름과 사용할 API를 선택하면 된다. 필수값으로 사용할 것들을 체크!

그리고 환경추가에서 이제 사용할 주소를 입력해주자! 개발상태기때문에 로컬 주소를 입력해주었다.

http://localhost:3000/api/auth/callback/naver

- Callback URL도 naver는 이렇게 입력해주어야한다. 사용하는 로컬포트 또는 도메인을 입력해주어야 한다.

 


정말 쉽죠? 생각보다 어려운 단계는 없다.

어떻게보면 기존에 회원가입 로그인을 구현하는것보다 Oauth를 사용하여 로그인 단계를 두는것이 더 편하게 작업할 수 있는것 같기도 하다. OAuth를 사용하면 서비스적인 면에서 유저들은 어떻게보면 가입을 하지않고 접근할 수 있기 때문에 더 편하게 다가가는것 같기도 하다!

 

 

 

 

참고

Setup and Use NextAuth.js in Next.js 13 App Directory

- [Next.js 13]Next.js 13.2버젼에 Next-auth 구현하기(+ 네이버 소셜 로그인)