- Published On
NextAuth.js 인증 구현하기
NextAuth.js는 Next.js 애플리케이션에서 쉽게 인증 기능을 구현할 수 있도록 도와주는 라이브러리입니다.
NextAuth.js v5(beta)가 최신 버전이지만 v4를 가장 많이 사용하여 v4에 대해 알아보겠습니다.
NextAuth.js란?
NextAuth.js는 Next.js 애플리케이션을 위한 완전한 인증 솔루션입니다.
OAuth, 이메일/비밀번호, SMS 등 다양한 인증 방식을 지원하며, 보안성과 확장성을 갖춘 라이브러리입니다.
- 다양한 인증 제공자 지원: Google, Facebook, Twitter, GitHub 등 여러 소셜 로그인 제공자를 지원합니다.
- 보안성: JWT(JSON Web Token)와 세션을 모두 지원하여 안전한 인증 관리를 제공합니다.
- 확장성: 커스터마이징이 용이하며, 다양한 설정 옵션을 제공합니다.
프로젝트 설정
- NextAuth.js 설치 NextAuth.js를 프로젝트에 추가합니다. 다음 명령어를 실행하여 NextAuth.js와 관련 종속성을 설치합니다.
prisma는 개발에서만 필요하므로 --save-dev
로 설치해주세요.
npm install next-auth
npm install --save-dev prisma
npm install @prisma/client @auth/prisma-adapter
- API 라우트 설정
NextAuth.js를 설정하려면 API 라우트를 생성해야 합니다.
pages/api/auth/[...nextauth].js
혹은 app/api/auth/[...nextauth]/route.js
파일을 생성합니다.
- 그리고 prisma client와, PrismaAdapter를 불러고 옵션을 설정합니다.
import NextAuth from "next-auth"
import { PrismaAdapter } from "@auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: PrismaAdapter(prisma),
providers: [],
})
- 단, 대부분 authOption 부분은 따로 빼서 작성합니다.
import NextAuth from 'next-auth';
import { authOptions } from '@/libs/auth-options';
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
- 환경 변수 설정
사용할 Oauth가 있다면 환경변수를 config 파일
, .env 파일
등에 설정해 줍니다.
module.exports = {
env: {
GOOGLE_CLIENT_ID: 'your-google-client-id',
GOOGLE_CLIENT_SECRET: 'your-google-client-secret',
DATABASE_URL: 'your-database-url',
NEXTAUTH_SECRET: 'your-nextauth-secret',
},
};
- prisma 설정
-
npx prisma init
-> schema 설정 ->npx prisma migrate dev --name init
-
아래의 예시 코드는 mysql을 기준으로 작성 및 설명하였습니다.
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
name String?
username String? @unique
email String? @unique
emailVerified DateTime?
image String?
Session Session[]
Account Account?
// Optional for WebAuthn support
Authenticator Authenticator[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Account {
id String @id @default(cuid())
userId String @unique
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
refresh_token_expires_in Int?
user User? @relation(fields: [userId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([provider, providerAccountId])
@@index([userId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([userId])
}
model VerificationToken {
identifier String
token String
expires DateTime
@@unique([identifier, token])
}
// Optional for WebAuthn support
model Authenticator {
credentialID String @unique
userId String
providerAccountId String
credentialPublicKey String
counter Int
credentialDeviceType String
credentialBackedUp Boolean
transports String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@id([userId, credentialID])
}
여기서는 가장 많이 사용되는 PrismaAdapter
를 기준으로 설명합니다.
PrismaAdapter는 기본적으로 위의 Table형식에 맞추서 데이터가 저장되며, 이를 수정하고 싶으면 authOptions
을 커스터마이징 하여야합니다.
모델 | 설명 | 옵션 |
---|---|---|
model User | 유저의 기본 정보가 저장되는 모델입니다. | 필수 |
model Account | OAuth로 로그인/회원가입 시 정보가 저장되는 모델입니다. | Oauth 사용 시 |
model Session | authOptions에서 저장 방식을 Session으로 할 경우 필요한 모델입니다. | session 저장 사용 시 |
model VerificationToken | authOptions에서 이메일 인증을 구현한 경우 필요한 모델입니다. | 이메일 인증 사용 시 |
authOptions
import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import { PrismaAdapter } from '@next-auth/prisma-adapter';
import { prisma } from '@/lib/prisma'; // Prisma 클라이언트 불러오기
export const authOptions = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
// 다른 제공자 설정 가능
],
adapter: PrismaAdapter(prisma), // Prisma 어댑터 설정
secret: process.env.NEXTAUTH_SECRET, // 보안을 위한 secret
session: {
strategy: 'jwt', // JWT 사용 여부
},
callbacks: {
async jwt({ token, user }) {
if (user) {
token.id = user.id;
}
return token;
},
async session({ session, token }) {
session.user.id = token.id;
return session;
},
},
};
export default NextAuth(authOptions);
- providers
설명: 인증 제공자를 정의합니다. 여러 소셜 로그인 제공자(Google, Facebook, GitHub 등)를 추가할 수 있습니다.
예시: GoogleProvider, FacebookProvider 등.
- adapter
설명: 데이터베이스 어댑터를 설정합니다. NextAuth.js는 Prisma, TypeORM, MongoDB 등 다양한 어댑터를 지원합니다.
예시: PrismaAdapter, TypeORMSessionAdapter 등
- secret
설명: JWT 또는 세션의 암호화에 사용되는 비밀 키입니다. 보안을 위해 환경 변수로 설정하는 것이 좋습니다.
예시: process.env.NEXTAUTH_SECRET
- session
설명: 세션 관리 방법을 정의합니다. JWT를 사용할지 또는 데이터베이스 세션을 사용할지 설정합니다.
옵션:
-
strategy: 'jwt' 또는 'database'(session)
-
maxAge: 세션의 최대 유효 기간(초)
-
updateAge: 세션 갱신 간격(초)
session: {
strategy: 'jwt', // JWT 사용 여부
maxAge: 30 * 24 * 60 * 60, // 30일
updateAge: 24 * 60 * 60, // 하루
}
- callbacks
설명: 인증 과정에서 호출되는 콜백 함수들을 정의합니다. 주로 JWT와 세션을 커스터마이징하는 데 사용됩니다.
옵션:
- jwt: JWT를 생성하거나 수정할 때 호출됩니다.
- session: 세션(db)을 생성하거나 수정할 때 호출됩니다.
- signIn: 사용자가 로그인할 때 호출됩니다.
- redirect: 로그인 후 리디렉션할 URL을 설정합니다.
- signOut: 사용자가 로그아웃할 때 호출됩니다.
jwt 콜백 함수 예시
사용자가 로그인할 때 JWT가 생성되며, 이후 요청마다 이 콜백이 호출되어 JWT를 수정할 수 있습니다.
async jwt({ token, user }) {
if (user) {
token.id = user.id;
}
return token;
}
이전 포스트
로그인 저장 방식 및 인증 방법다음 포스트
OAuth(소셜 로그인)의 구동 원리연관된 포스트 구경가기