NextAuth.js로 소셜 로그인 만들기

milmil·2023년 4월 29일
0

PICK ME UP (가제)

목록 보기
1/1
post-thumbnail

이제 로그인 기능을 붙여보겠다. NextAuth.js는 구현하기 귀찮은 인증 기능을 아주 쉽고 간단하게 만들 수 있게 해준다. 이전에도 이 블로그에, oauth 관련 포스팅을 한 적이 있다.

프론트엔드/리액트 카카오 로그인
백엔드/node.js/express 카카오 로그인
트위터 oauth1.0 인증
직접 구현하는 것은 하려고 하면 할 수는 있지만 생각할 것도 많고 번거롭고 이게 맞나..? 하는 생각이 든다. (그래도 직접 한 번은 구현 해 보면 도움이 된다.)

이제 이 과정을 간단하게 넘겨버리자.
...그러려고 했는데 신기술은 언제나 학습의 귀찮음이 따른다.

Getting Started

$yarn add next-auth

이걸 설치한 다음에

https://next-auth.js.org/getting-started/example
그냥 공식 문서 그대로 따라하면 되고 굳이 다시 쓰지는 않겠다. (귀찮다.)

...

const getEnv = (key: string) => {
  const value = process.env[key];
  if (!value) {
    throw new Error(`${key}: 존재하지 않는 환경 변수`);
  }
  return value;
};

export default getEnv;

utils/getEnv.ts 파일을 만들었다. 이것으로 환경 변수를 불러오면, 오류를 던져주기 때문에 삽질을 줄일 수 있다.

그 다음엔 난 orm 으로 prisma, db는... 그냥 쓰던 게 편해서 mysql로 하겠다.

암튼 공식 문서를 보다보면 밑에 이런 게 있음.

(코드를 이미지로 올려놓은 것은 여러분을 열받게 하려고 그런 게 아니고 공식문서에 있기 때문입니다.)

이게 뭔 내용인지 이해도 안 되었는데, 일단 jwt는 oauth 에서 토큰 받을 때마다 실행이 되고 session은 session 데이터 가져올 때 실행이 된다고 함. 세션에는 기본적으로 설정되어 있는 것만 가져올 수 있고 이외의 것(예를 들어, 이메일이라든가...)가져오려면 명시적으로 추가해줘야 한다.

근데 저 코드를 무지성으로 타입스크립트에서 복붙하면 에러를 뱉음 (아놔..)

해결법은 AuthOptions 를 Import해서 타입을 붙여주는 것이다.

import NextAuth, { AuthOptions } from 'next-auth';



const prisma = new PrismaClient();
export const authOptions: AuthOptions = { //여기
  providers: [
   ...
  ],
};
export default NextAuth(authOptions);

이렇게 하면 고쳐짐. 그리고 types/next-auth-d.ts 파일을 만든 뒤

import NextAuth, { DefaultSession } from 'next-auth';

declare module 'next-auth' {
  /**
   * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
   */
  interface Session {
    accessToken: string;
    user: {
      accessToken: string;
    } & DefaultSession['user'];
  }
}

declare module 'next-auth/jwt' {
  interface JWT {
    accessToken: string;
  }
}

이런식으로 커스텀 프로퍼티를 추가해주면 된다.
...되긴 되는데

그런데 나는 프리즈마 어댑터를 쓸 거라 그냥 안 하기로 함.

https://authjs.dev/reference/adapter/prisma
이것도 그냥 공식문서를 보자.

복붙을 하고 만들라는 파일을 만들고 db 서버가 로컬이면 실행도 해주고 올바른 db url을 만들고 이것저것 하고 마이그레이션도 하면 알아서 다 해준다.

import { useSession, signIn, signOut } from 'next-auth/react';
export default function Component() {
  const { data: session } = useSession();

  if (session) {
	console.log(session)
    return (
      <>
        Signed in as {session.user?.email} <br />
        <button onClick={() => signOut()}>Sign out</button>
      </>
    );
  }
  return (
    <>
      Not signed in <br />
      <button onClick={() => signIn('discord')}>Sign in</button>
    </>
  );
}

하지만 기본 제공하는 인증 창 보다는 커스텀한 디자인을 쓰고 싶으니 이런식으로 signIn, signOut 함수를 버튼에 붙일 수 있다.

하지만 디자인은 아직 없다.😃

누르면 나의 경우 디스코드 인증창이 뜨고, 승인을 하고 돌아오면 이메일이 표시되며 사인 아웃 버튼으로 바뀐다.

db에도 잘 저장이 된다.

정말 쉽게 로그인을 만들었다.

아직 모든 게 다 익숙하지 않고 프리즈마는 또 어떻게 다루는 건지 하나도 모르지만 로그인만은 구현완료했다!

다음에는 뭘 할지 그건 다음에 생각해보겠다. 그리고 프리즈마에 대해서도 좀 더 알아보아야 한다. (뭐가 어쨌든 sequelize 문서를 보는 것보단 낫지 않을까 싶다)

profile
쓰고 싶은 글만 씀

0개의 댓글