[Next.js] authjs(NextAuth)를 활용한 인증 기능 구현하기(2) : 구글 로그인 Database Adapter 설정하기

문지은·2024년 1월 24일
1

Next.js - App Router

목록 보기
13/20
post-thumbnail

구글 로그인을 이용했을 때 사용자 정보를 데이터베이스에 저장하기 위해 데이터베이스 어댑터를 설정해보자.

현재 프로젝트에서 프리즈마 데이터베이스를 사용하고 있으므로 프리즈마 어댑터를 등록한다.

npm install @prisma/client @auth/prisma-adapter
npm install prisma --save-dev
  • nextauth 인증 라우트에 어댑터 추가
    • 프리즈마 어댑터를 등록하고, 인자값으로 프리즈마 클라이언트 전달

app/api/auth/[…nextauth]/route.ts

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

export const authOptions = {
  adapter: PrismaAdapter(prisma),
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
};

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };
  • 다른 경로를 통해 들어온 사용자 정보 및 토큰 정보를 저장할 수 있는 형태로 데이터베이스 스키마 수정
    • 공식 문서에 있는 코드 사용하여 스키마 수정하기 전에, 데이터베이스 충돌을 방지하기 위해 현재 스키마에 정의된 모델을 삭제하고 마이그레이션 명령어를 실행하자.
npx prisma migrate dev
  • 공식 문서에서 제공하는 스키마 파일을 붙여 넣고, 다시 마이그레이션 실행

prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

model Account {
  id                 String  @id @default(cuid())
  userId             String
  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?

  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])
}
npx prisma migrate dev
  • 데이터베이스를 확인하면, 4개의 모델이 생성된 것을 확인할 수 있다.

  • 하지만 브라우저에서 구글 로그인을 시도하면, 로그인 완료 후 홈페이지로 리다이렉트 되지 않는 오류가 발생한다.

  • 세션 전략이 기본적으로 JWT 으로 동작하는데, 어댑터를 사용하면 세션 방식으로 동작하기 때문이다.
    • 세션 방식을 JWT 형식으로 수정하면 된다.
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import { PrismaAdapter } from "@auth/prisma-adapter";
import prisma from "@/prisma/client";

export const authOptions = {
  adapter: PrismaAdapter(prisma),
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
	// 세션 방식 - JWT 추가 
  session: {
    strategy: "jwt",
  },
};

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };
  • 다시 브라우저에서 로그인을 해보면, 성공적으로 홈페이지가 리다이렉트 된다.
  • 데이터 베이스를 살펴보면, User 테이블에 구글 로그인 한 사용자의 이름, 이메일, 이미지 등이 저장된 것을 확인할 수 있다.

profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

0개의 댓글