설치

npm install next-auth

API 라우트 설정

import NextAuth, { NextAuthOptions } from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';

import { fetchSignIn, fetchUser } from '@/app/api/auth';

const handler = NextAuth({
  providers: [
    CredentialsProvider({
      id: 'credentials',
      name: 'Credentials',
      credentials: {
        email: {
          label: 'Email',
          type: 'text',
          placeholder: '[email protected]',
        },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials) {
        const {
          data: { access_token },
        } = await fetchSignIn({
          email: credentials?.email || '',
          password: credentials?.password || '',
        });
        const user = await fetchUser();
        const id = access_token.split('|')[0] || '';

        if (user) {
          return {
            ...user.data,
            id,
          };
        } else {
          return null;
        }
      },
    }),
  ],
  callbacks: {
    async jwt({ token, user, trigger }) {
      if (trigger === 'update') {
        const updateUser = await fetchUser();
        return { ...token, ...user, ...updateUser.data };
      }
      return { ...token, ...user };
    },

    async session({ session, token }) {
      session.user = token as never;
      return session;
    },
  },
  pages: {
    signIn: '/signin',
  },
} as NextAuthOptions);
export { handler as GET, handler as POST };

환경 변수 설정

NEXTAUTH_URL=your-service-domain // ex: <http://localhost:3000>
NEXTAUTH_SECRET=yout-secret-key
/** @type {import('next').NextConfig} */
const nextConfig = {
	// ...
  env: {
    APP_API_URL: process.env.APP_API_URL,
    NEXTAUTH_URL: process.env.NEXTAUTH_URL,
    NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
  },
  // ...
};

module.exports = nextConfig;

유저 데이터 타입 설정

import { DefaultSession } from 'next-auth';

interface UserData {
  created_at: string;
  email: string;
  name: string;
  nickname: string | null;
  phone: string | null;
  provider: string | null;
}

declare module 'next-auth' {
  interface Session {
    user: UserData & DefaultSession['user'];
  }
}

클라이언트 API

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

export default function AuthButton() {
  const { data: session } = useSession();

  if (session) {
    return (
      <>
        <p>Signed in as {session.user.email}</p>
        <button onClick={() => signOut()}>Sign out</button>
      </>
    );
  }

  return <button onClick={() => signIn()}>Sign in</button>;
}

미들웨어 설정

export { default } from 'next-auth/middleware';

export const config = {
  matcher: ['/account'],
};