[Next.js] next-auth 간단한 사용법과 유의사항

js43o·2023년 6월 27일
2

Next.js 프로젝트에서 next-auth 라이브러리를 이용해 SNS 로그인을 보다 쉽고 간편하게 적용할 수 있다.

0. OAuth 서비스 설정

  • 먼저 원하는 OAuth 서비스에 내 앱을 등록하고 필요한 정보들을 받아둔다. GitHub에서는 Client ID, Client secrets가 제공된다.
  • Authorization callback URL/[origin]/api/auth/callback/[provider] 형식으로 적어주자.

1. 루트 감싸기

  • 최상단 컴포넌트인 _app.tsx에서 반환되는 JSX를 SessionProvider로 감싼다.
// pages/_app.tsx
export default function App({ Component, pageProps, ...appProps }: AppProps) {
  return (
    <>
      <SessionProvider session={pageProps.session}>
        ...
      </SessionProvider>
    </>
  );
}

2. NextAuth 객체 생성

  • 필요한 DB 어댑터와 OAuth 서비스 제공자 목록을 NextAuth의 인수로 전달한다. 인증 과정에서 이 API 파일이 사용될 것이다.
  • 위에서 받은 Client ID와 Client Secret을 .env 파일에 저장하고 GithubProvider의 인수로 전달한다.
// pages/api/auth/[...nextauth].ts
import NextAuth from 'next-auth';
import GithubProvider from 'next-auth/providers/github';
import { MongoDBAdapter } from '@next-auth/mongodb-adapter';
import clientPromise from 'utils/db/functions/clientPromise';

export default NextAuth({
  providers: [	// 서비스 제공자 목록
    GithubProvider({
      clientId: process.env.GITHUB_ID as string,
      clientSecret: process.env.GITHUB_SECRET as string,
    }),	// GitHub에서 발급받은 문자열 전달
  ],
  secret: process.env.JWT_SECRET,	// JWT를 위한 비밀 키
  pages: {
    signIn: '/auth/login',	// 로그인 페이지 경로
  },
  adapter: MongoDBAdapter(clientPromise),	// MongoDB 어댑터
  callbacks: {
    session: async ({ session, token, user }) => {
      if (session.user) {
        session.user.id = user.id;	// 세션에 사용자 ID를 저장함
      }

      return session;
    },
  },
});

3. 로그인, 세션 정보

  • 로그인 페이지에서 signIn 함수를 호출하여 특정 로그인 서비스를 실행시키도록 한다. 이때 로그인이 끝난 후 돌아갈 페이지 URL을 같이 전달한다.
  • 현재 사용자의 세션 정보는 useSession hook으로 가져올 수 있다.
  • 로그아웃은 signOut 함수를 호출하는 것으로 간단하게 처리 가능하다.
// pages/auth/login.tsx
import { signIn, useSession } from 'next-auth/react';

export default function Login() {
  const { data, status } = useSession();
  const callbackUrl = process.env.NEXT_PUBLIC_HOMEPAGE_URL as string;
  
  if (status !== 'authenticated') {
  	return <Button onClick={() => signIn('github', { callbackUrl })} />
  }
}

여기까지 만들었을 때, 로컬 환경에서는 로그인 기능이 문제 없이 잘 작동하였으나, AWS EC2 환경에 배포를 하니 문제가 발생하였다.
배포 도메인이 http://myapp.com이고 콜백 URL이 http://myapp.com/api/auth/callback/github일 때,
로그인 버튼을 누르면 현재 주소의 오리진이 http://myapp.com이 아닌 http://localhost:3000으로 바뀌어 버린다.

분명 GitHub OAuth에서 Homepage URL과 Authorization callback URL도 잘 바꾸었고, .env파일의 NEXT_PUBLIC_HOMEPAGE_URL도 수정했는데, 로그인만 하려 하면 저쪽 서버에서 내 로컬 서버로 넘어가버린다. 코드에는 'localhost'라는 단어조차 찾을 수 없었다.

문제의 원인은 이랬다.

4. 배포 시 환경변수 설정

개발 환경이 아닌 실제 배포 환경에서는 반드시 NEXTAUTH_URL 환경변수를 .env 파일에 포함시켜야 한다! 그렇지 않으면 NextAuth가 기본값인 localhost:3000을 콜백 및 리다이렉트 URL로 사용하게 된다.

역시 이해할 수 없는 이상한 에러가 발생하면 가장 먼저 공식 문서부터 참고하도록 하자.

Reference

https://stackoverflow.com/questions/71109710/next-auth-deployed-code-redirecting-me-to-localhost-on-login

profile
공부용 블로그

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

NEXTAUTH_URL 크... 꿀팁 감사합니다!

답글 달기