next auth + prisma

Posted by : on

Category : nextJs


Next-auth & Prisma 같이 사용하기

import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

export default NextAuth({
  adapter: PrismaAdapter(prisma),
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
});

Next-auth 세팅

  1. NextAuth 설치
    • yarn add next-auth
  2. .env 파일에 NEXTAUTH_URL 환경변수 추가
    • NEXTAUTH_URL=http://localhost:3000
  3. API Route 추가
    • Pages/api/auth 경로에 [...nextauth].js 파일 생성
    • 파일 내부에 원하는 인증 공급자 및 옵션 설정

/pages/api/auth/[…nextauth].js 파일 코드 예시

import NextAuth from "next-auth";
import GithubProvider from "next-auth/providers/github";

export const authOptions = {
  // 여러 인증 공급자 설정 가능
  providers: [
    GithubProvider({
      clientId: process.env.GITHUB_ID,  // GitHub OAuth 인증에 필요한 클라이언트 ID
      clientSecret: process.env.GITHUB_SECRET,  // GitHub OAuth 인증에 필요한 클라이언트 시크릿
    }),
    // 다른 인증 공급자 추가 가능
  ],
};

export default NextAuth(authOptions);
  1. _app.js 파일에 Session Provider 설정
import { SessionProvider } from "next-auth/react";

export default function App({ Component, pageProps: { session, ...pageProps } }) {
  return (
    <SessionProvider session={session}>
      <Component {...pageProps} />
    </SessionProvider>
  );
}
  1. useSession() 및 인증 후 사용자 관리
import { useSession, signIn, signOut } from "next-auth/react";

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

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

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


Prisma Adapter 세팅

https://next-auth.js.org/v3/adapters/prisma

  • Prisma Adapter를 설치하고 next-auth 파일에 설정합니다.
  1. Prisma Adapter 설치
yarn add @auth/prisma-adapter
  1. Next-auth 파일에 Prisma 설정
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import { PrismaAdapter } from "@auth/prisma-adapter";
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

export default NextAuth({
  adapter: PrismaAdapter(prisma),
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
});

prisma.schema 파일에 스키마를 정의해주고, migrate를 합니다.

  1. Prisma 스키마 예시
model Account {
  id                 String   @id @default(cuid())
  userId             String
  type               String
  provider           String
  providerAccountId  String
  refresh_token      String?  @db.Text
  access_token       String?
  expires_at         Int?
  token_type         String?
  scope              String?
  id_token           String?  @db.Text
  session_state      String?

  user               User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  @unique([provider, providerAccountId])
}

model Session {
  id           String   @id @default(cuid())
  sessionToken String   @unique
  userId       String
  expires      DateTime
  user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model User {
  id            String   @id @default(cuid())
  name          String?
  email         String?  @unique
  emailVerified DateTime?
  image         String?
  accounts      Account[]
  sessions      Session[]
}

model VerificationToken {
  identifier String
  token      String   @unique
  expires    DateTime
  @unique([identifier, token])
}

Middleware 세팅

  • 특정 경로에서 항상 로그인을 해야하는 경우, middleware를 통해 보안을 걸 수 있습니다.
  • .env 파일에 NEXTAUTH_SECRET을 생성 후, 반드시 로그인에 필요한 페이지 경로를 Middleware를 통해 정의합니다. https://next-auth.js.org/configuration/nextjs#middleware
    1. /src/middleware.ts 예시:
// middleware.ts
export { default } from 'next-auth/middleware';

export const config = {
  matcher: ['/users/mypage', '/stores/new', '/stores/:id/edit'],
};

About 유재석
유재석

개발자 유재석 입니다. Web Developer.

Email : jaeseok9405@gmail.com

Website : https://github.com/yoo94