NextAuth를 사용한 인증 구현하기

zooyaho·2023년 8월 15일
2
post-thumbnail
post-custom-banner

NextAuth를 사용한 인증 구현하기

NextAuth는 Next.js 프로젝트에서 인증을 쉽게 구현할 수 있게 도와주는 라이브러리입니다. 이 포스트에서는 pages/api/auth/[...nextauth].ts 파일에 대한 설명을 중점적으로 다룰 예정입니다.

NextAuth 구성 객체

NextAuth의 설정은 pages/api/auth/[...nextauth].ts 파일에서 수행하며, 기본 구조는 다음과 같습니다:

import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

export default NextAuth({
  // 여기에 구성 객체가 위치함
});

⚫ Providers

providers는 사용할 인증 방법을 정의합니다. 여러 인증 방법이 있지만, 이 예시에서는 Credentials 방법을 사용합니다.

providers: [
  Providers.Credentials({
    name: 'Credentials',
    credentials: {
      username: { label: "Username", type: "text" },
      password: { label: "Password", type: "password" }
    },
    authorize: async (credentials) => {
      // 로그인 로직
    },
  }),
],

📑 Providers.Credentials 구성

  1. name
  • name: 이 필드는 인증 제공자의 이름(프로바이더의 이름)을 정의합니다. 사용자가 인증 방법을 선택할 때 보여지는 제목이 될 수 있습니다.
  • 예시: name: 'Credentials'는 "Credentials"라는 이름으로 제공자를 표시합니다.
  1. credentials
  • credentials: 이 필드는 인증에 사용될 자격 증명의 형식(사용자로부터 입력 받을 필드를 정의)을 정의합니다. 객체 형식으로 각 자격 증명의 레이블과 유형을 설정할 수 있습니다.
  • 예시:
    1) username: 사용자 이름 입력 필드를 정의하며, 레이블은 "Username"이고, 입력 유형은 텍스트입니다.
    2) password: 비밀번호 입력 필드를 정의하며, 레이블은 "Password"이고, 입력 유형은 패스워드입니다.
  1. authorize: 로그인을 처리하는 함수입니다. 이 함수는 사용자가 입력한 credentials를 인자로 받아 로그인 로직을 처리합니다.

⚫ Callbacks

callbacks는 인증 프로세스 중 다양한 시점에서 호출되는 함수를 정의합니다.

callbacks: {
  session: async (session, user) => {
    session.token = user.token;
    return session;
  },
  jwt: async (token, user) => {
    if (user) {
      token = user.token;
    }
    return token;
  },
},

📑 Callbacks 구성

  1. session 콜백
  • 역할: 사용자의 세션 객체를 사용자 정의하고 조작할 수 있게 합니다.
  • 입력 매개변수:
    1) session: 현재 세션 객체
    2) user: authorize 메서드에서 반환된 사용자 객체
  • 예시: 위 코드에서는 user.token을 세션 객체에 추가하고 있습니다. 이렇게 하면 해당 토큰을 프론트 엔드에서 사용할 수 있게 됩니다.
  • 반환값: 수정된 세션 객체. 이 객체는 클라이언트 측에서 useSession 훅을 통해 액세스할 수 있습니다.
  1. jwt 콜백
  • 역할: JWT (JSON Web Token)의 생성과 검증을 사용자 정의하고 조작할 수 있게 합니다. NextAuth에서 내부적으로 JSON Web Token(JWT)를 관리하고 조작하는 데 사용됩니다.
  • 입력 매개변수:
    1) token: 현재 JWT 토큰
    2) user: authorize 메서드에서 반환된 사용자 객체 (로그인 시에만 제공됩니다)
  • 예시: 위 코드에서는 사용자가 로그인하는 경우 user.token 값을 JWT 토큰에 할당합니다. 이를 통해 토큰 안에 특정 사용자 정보를 포함시킬 수 있습니다.
  • 반환값: 수정된 토큰 객체. 이 토큰은 이후 세션 관리와 관련된 모든 동작에서 사용됩니다.

예시

1. [...nextauth].ts 파일 작성

pages/api/auth/[...nextauth].ts 파일을 만들고 다음 코드 작성

import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

export default NextAuth({
  providers: [
    Providers.Credentials({
      name: 'Credentials',
      credentials: {
        username: { label: "Username", type: "text" },
        password: { label: "Password", type: "password" }
      },
      async authorize(credentials) {
        const response = await fetch('http://your-api-endpoint.com/api/login', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(credentials),
        });

        const data = await response.json();

        if (response.ok && data.token) {
          return { token: data.token, rfToken: data.rfToken };
        } else {
          // 로그인 실패 시 처리
          throw new Error('Login failed!');
        }
      },
    }),
  ],
  callbacks: {
    session: async (session, user) => {
      session.token = user.token;
      return session;
    },
    jwt: async (token, user) => {
      if (user) {
        token = user; // { token: data.token, rfToken: data.rfToken }
      }
      return token;
    },
  },
});

👉🏻 이 코드는 ID와 비밀번호를 받아와 api/login 엔드포인트에 POST 요청을 보내고 토큰을 받아옵니다.

2. 로그인 컴포넌트

로그인 폼 컴포넌트에서 signIn 함수를 사용해 로그인 수행

import { signIn } from 'next-auth/react';

function Login() {
  const handleSubmit = (e) => {
    e.preventDefault();
    const username = e.target.username.value;
    const password = e.target.password.value;

    signIn('credentials', { 
      username,
      password,
      callbackUrl: '/' // 로그인 성공 후 리다이렉션 할 URL
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="username" required />
      <input type="password" name="password" required />
      <button type="submit">Login</button>
    </form>
  );
}

export default Login;

🌈 실행 순서

  1. 사용자 로그인: 사용자가 로그인 폼을 제출하면, signIn 함수가 호출되고, 내부적으로 authorize 메서드가 실행됩니다.

  2. 인증 확인: authorize 메서드는 백엔드 서버와 통신하여 사용자 인증을 확인합니다. 인증이 성공하면 토큰을 반환합니다.

  3. JWT 생성: authorize 메서드의 반환 값이 jwt 콜백에 전달됩니다. 여기에서 반환된 토큰은 jwt 콜백 내에서 token 객체에 할당됩니다.

  4. 세션 생성: jwt 콜백에서 반환된 token 객체가 session 콜백으로 전달됩니다. session 콜백은 이 token을 세션 객체에 할당하고 클라이언트에게 반환합니다.

  5. 클라이언트 측 세션: 클라이언트 측에서는 useSession 등의 훅을 통해 세션 데이터에 접근할 수 있으며, 여기에는 jwt 콜백에서 할당한 token 정보가 포함되어 있습니다.

따라서, 발급한 토큰은 jwt 콜백을 통해 Next.js 서버의 JWT 토큰에 저장되고, 이 정보는 다시 세션 객체로 변환되어 클라이언트에게 전달됩니다.

정리

NextAuth는 Next.js에서 인증을 손쉽게 관리할 수 있게 해주는 강력한 라이브러리입니다. 이 포스트에서는 pages/api/auth/[...nextauth].ts 파일을 사용한 기본적인 인증 구현 방법을 설명했습니다. 실제 프로젝트에서는 추가적인 보안과 에러 처리 등을 고려해야 할 수 있으니, 자세한 정보는 NextAuth 공식 문서를 참조하세요.

profile
즐겁게 개발하자 쥬야호👻
post-custom-banner

2개의 댓글

comment-user-thumbnail
2023년 8월 15일

잘 읽었습니다. 좋은 정보 감사드립니다.

답글 달기
comment-user-thumbnail
2024년 8월 24일

"실행 순서" 정리 부분 도움 많이 되었어요! 😄

답글 달기