프론트엔드/Next.js

Auth.js(Next Auth) 사용자 인증 쉽게 구현하기

다소스랩 2024. 11. 14. 14:58
반응형

Auth.js 사이트 메인

 

Auth.js는 구글, 카카오, 네이버 등 다양한 로그인 방법을 제공해 사용자 인증 및 세션 관리를 쉽게 구현할 수 있도록 하는 라이브러리입니다. 구글, 카카오 등과 같은 소셜 로그인 서비스를 Auth.js에서는 인증 프로바이더라고 합니다.

 

Auth.js는 NextAuth의 이름이 변경된 버전이기 때문에, 이 라이브러리를 처음 접하시는 분들은 혼동할 수 있습니다. 초기에 Next Auth라는 이름으로 Next.js 프레임워크를 대상으로 개발되었는데, 현재는 Javascript의 다른 프레임워크나 서버 환경에서도 사용될 수 있도록 확장하면서 Auth.js로 이름을 변경했습니다.

 

Next Auth로 검색하면 v4 사이트가 나오고, Auth.js로 검색하면 v5 사이트가 나오는데 이 글은 v5를 기준으로 작성되었다는 점 참고해 주세요.

데모 사이트 둘러보기

Auth.js 데모 사이트

Auth.js 라이브러리를 사용해 보기에 앞서 데모 사이트를 보고 오시면 Auth.js가 어떤 라이브러리인지 바로 알 수 있습니다. Auth.js는 다양한 소셜 로그인을 지원하며 클라이언트 측과 서버 측 모두 사용할 수 있습니다.

 

설치

# Auth.js v5 설치
npm install next-auth@beta

@beta를 붙이지 않으면 v4가 설치되니 주의해 주세요.

# 비밀키 생성
npx auth secret

이 명령어를 실행하면. env 파일이 생기고 AUTH_SECRET 비밀키가 생성됩니다. 비밀키는 사용자의 세션 정보와 토큰 데이터를 암호화하고 서명하는 데 사용되는 필수 환경 변수입니다.

 

설정 코드

Auth.js 설정을 하나씩 살펴보겠습니다.

기본

import NextAuth from "next-auth";

export const {
  handlers,
  signIn,
  signOut,
  auth,
} = NextAuth({
  secret: process.env.AUTH_SECRET,
  basePath: "/auth",
  session: { strategy: "jwt" },
});
  • secret: 환경변수를 주입해 줍니다.
  • basePath: Auth.js의 기본 경로는 `api/auth`입니다. 경로를 바꾸고 싶다면 basePath에 경로를 지정해 주면 됩니다.
  • session: 세션을 관리하는 방식을 지정합니다. jwt(클라이언트 측 관리)와 database(서버 측 관리)가 있습니다.

 

프로바이더

import NextAuth from "next-auth";
import Google from "next-auth/providers/google";
import Kakao from "next-auth/providers/kakao";

export const {
  handlers,
  signIn,
  signOut,
  auth,
} = NextAuth({
  //...생략
  providers: [
    Google({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
      authorization: {
        params: {
          prompt: "consent",
        },
      },
    }),
    Kakao,
  ],
});
  • providers는 배열로 프로바이더들을 받습니다. (사용 가능한 프로바이더 목록 확인하기)
  • Google, Kakao 등 다양한 프로바이더의 OAuth 설정에서 redirect URL을 등록하게 되는데, 이 경로는 basePath 설정에 따라 달라집니다.
    • 기본 경로: `/api/auth/callback/{provider}`
    • basePath를 '/auth'로 지정했을 경우: `/auth/callback/{provider}`
  • `AUTH_` 프리픽스로 시작되는 환경변수들은 자동으로 주입됩니다.

 

# .env

GOOGLE_ID=""
GOOGIE_SECRET=""

# Auth.js 환경변수
AUTH_KAKAO_ID=""
AUTH_KAKAO_SECRET=""

 

구글은 AUTH 프리픽스를 사용하지 않아서 프로바이더에서 직접 주입해야 하지만, 카카오는 AUTH 프리픽스를 사용해서 자동으로 주입됩니다.

 

콜백

콜백은 인증 과정에서 특정 단계에서 실행되는 함수입니다. 모든 콜백함수는 비동기와 동기 모두 사용할 수 있습니다.

import NextAuth from "next-auth";

export const {
  handlers,
  signIn,
  signOut,
  auth,
} = NextAuth({
  //...생략
  callbacks: {
    // JWT 토큰을 수정할 때 실행됩니다.
    async jwt({ account, token, user, profile, session, trigger }) {
      // 사용자가 로그인할 때 JWT 토큰에 사용자 정보를 추가
      if (account) {
        token.id = account.id;
        token.email = account.email;
        token.accessToken = account.access_token;
      }
      return token;
    },

    // 세션 객체를 수정할 때 실행됩니다.
    async session({ session, token, user, trigger, newSession }) {
      // JWT 토큰에서 사용자 정보 가져와 세션 객체에 추가
      session.user.id = token.id;
      session.user.email = token.email;
      session.user.accessToken = token.accessToken;
      return session;
    },

    // 로그인 시 실행되며, 로그인 정보를 통해 조건을 설정할 수 있습니다.
    async signIn({ account, user, profile, email, credentials }) {
      // 구글 로그인만 허용
      if (account.provider === "google") {
        console.log("User logged in with Google:", user);
        return true; // 로그인 허용
      }
      return false; // 다른 제공자는 거부
    },

    // 사용자가 특정 리소스에 접근하려고 할 때 실행됩니다.
    async authorized({ auth, request }) {
      // 예시: 사용자가 'admin' 페이지에 접근하려면 관리자 권한이 필요
      if (request.url?.includes("/admin")) {
        if (auth.token?.role === "admin") {
          return true; // 관리자는 접근 허용
        }
        return false; // 관리자가 아니면 접근 거부
      }
      return true; // 다른 페이지는 모두 접근 허용
    },

    // 로그인 후 페이지 이동 시 실행됩니다.
    async redirect({ baseUrl, url }) {
      // 로그인 후 /dashboard로 리디렉션
      if (url === "/dashboard") {
        return `${baseUrl}/user-dashboard`; // 대시보드 페이지로 이동
      }
      return url; // 기본 URL 리디렉션
    },
  },
});

 

콜백 실행 순서는 아래와 같습니다.

  • 로그인/회원가입: signIn → (redirect - 필요한 경우) → jwt → session
  • 세션 업데이트: jwt → session
  • 세션 조회: jwt → session

 

페이지 경로 지정

import NextAuth from "next-auth";

export const {
  handlers,
  signIn,
  signOut,
  auth,
} = NextAuth({
  //...생략
  pages: {
    signIn: "/login",
    error: "/error",
  },
});

 

Auth.js는 기본적으로 내장된 로그인, 로그아웃, 에러 페이지를 제공합니다. 이런 페이지들을 커스텀 하고 싶다면 pages에서 경로를 지정해 줄 수 있습니다.

 

라우트

// auth/[...nextauth]/route.js
import { handlers } from "@/auth";
export const { GET, POST } = handlers;
  • 이 글에서는 Auth.js의 basePath를 `/auth`로 지정해 줬기 때문에 라우트 경로가 auth로 시작합니다.
  • basePath를 지정하지 않았다면 기본경로 `/api/auth/[... nextauth]/route.js`를 사용합니다.

 

미들웨어

export { auth as middleware } from "@/auth"

 

 

 

반응형