NextJs 풀스택 구축기 1 환경설정

OkGyoung·2023년 11월 8일
0

기존 damf4 사이트 리뉴얼을 위해 NextJs를 사용해 풀스택을 구축한 경험이다.

NextJs, Next-Auth 인증 구축

리뉴얼하며 사이트에 체류 시간을 늘리기 위해서 댓글 시스템과 별점 시스템, 라인업 시스템을 구축할 예정이다. 그 과정을 위해 먼저 인증처리를 한 후 나머지 과정을 진행하려한다. 자세한 과정은 링크참조

npx create-next-app

먼저 새로운 NextJs 프로젝트를 하나 만듭니다.(app route)

npm i next-auth

그리고 Next-Auth 또한 설치해줍니다.

Next-Auth의 [...nextauth].ts 파일을 중심으로 작동됩니다.

하지만 저희는 app route를 선택했기 때문 app/api/auth/[...nextauth] 폴더에 route.ts 파일을 만들어 이용합니다.

/** app/api/auth/[...nextauth]/route.ts */
import NextAuth from 'next-auth/next'

const handler = NextAuth({})

export { handler as GET, handler as POST }

그후 파일에 다음과 같이 작성합니다. ES6에 새로이 추가된 문법으로 export하는 모듈을 다음과 같이 설정하여 GET, POST로 나눌 수 있습니다.

자 그럼 본격적으로 많은 로그인 방식중 Credentials를 이용해 DB와 직접 이용하는 방법을 사용하도록 하겠습니다.

/** app/api/auth/[...nextauth]/route.ts */
import NextAuth from 'next-auth/next'
import CredentialsProvider from 'next-auth/providers/credentials'

const handler = NextAuth({
  providers: [
    CredentialsProvider({
      // 로그인 시 보여줄 문구
      name: 'Credentials',
      // `credentials` sign in page를 이용합니다.
      // 아래 처럼 다양한 키를 추가하고 이를 input을 통해 넣어주면 됩니다.
      credentials: {
        username: { label: 'Username', type: 'text', placeholder: 'jsmith' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials, req) {
        const user = { id: '1', name: 'J Smith', email: 'jsmith@example.com' }

        if (user) {
          // user를 JWT로 저장
          return user
        } else {
          // 에러 발생 시 항목
          return null
          // 에러 시 보여줄 페이지 혹은 다른 작업을 할 수 있습니다.
        }
      },
    }),
  ],
})

export { handler as GET, handler as POST }

이후 실제 npm run dev 후 /api/auth/signin로 이동하면 로그인 폼이 만들어진 것을 볼 수 있습니다.

하지만 여기서 끝이아니라 적절하게 로그인 성공 후 돌아갈 콜백을 지정해 주어야 합니다. 그리고 이는 env파일에 작성합니다.

NEXTAUTH_SECRET=super_secret
NEXTAUTH_URL=http://localhost:3000

자 이제 뼈대는 완성입니다. 이제 실제 authorize 함수 안에서는 로그인 로직을 처리 하는 과정입니다.

관련해서 ORM으로 Prisma를 DB MongoDB를 사용합니다. 이렇게 진행하는 이유는 후에 Vercel, MongoDB Atlas을 이용해 비용을 최소한으로 하기 위해서입니다. 물론 본인이 원하는 방식으로 해당 부분을 작성하여도 좋습니다.

npm i prisma -D

먼저 Prisma를 설치합니다.

npx prisma init

이후 초기화를 해줍니다. 그후 생성된 폴더 prisma/schema.prisma를 다음과 같이 변경해줍니다. 특히 Prisma는 내부 과정으로 env의 변수를 바로 가져오도록 설정되어 DATABASE_URL를 env파일에서 변경 후 작성하면 됩니다.

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

.env

NEXTAUTH_SECRET=super_secret
NEXTAUTH_URL=http://localhost:3000
DATABASE_URL="내 DB 주소"

이후 prisma/schema.prisma에서 스키마를 작성해 주면 됩니다.
바로 이부분이 ORM의 장점인 부분입니다. 적절한 모델을 작성하면 DB에 관계 없이 올바르게 저장됩니다.

그후 스키마에서 모델을 작성합니다. 자세한 사항

npx prisma db pull

만약 미리 사용하던 DB가 있다면 위 명령어를 통해 스키마를 가져올 수 있습니다.

prisma/schema.prisma

//...

model User {
  id       String  @id @default(auto()) @map("_id") @db.ObjectId
  email    String  @unique
  name     String?
  password String
}

model Post {
  id        Int     @id @default(autoincrement())
  title     String
  content   String?
  published Boolean @default(false)
  author    User    @relation(fields: [authorId], references: [id])
  authorId  Int
}

만약 없다면 위처럼 추가해줍니다. 위는 Prisma의 예제이고 실제로 본인이 사용할 모습으로 변경해주면 됩니다.

npx prisma studio

위는 테스트해 볼 수 있는 Prisma의 기능입니다. 아주 편리합니다!

자 이제 NextJs사용하기위해

npm i @prisma/client

prisma/client를 설치하고 이후에 설정을 하나 해야 합니다.

/app/utils/prisma.ts

import { PrismaClient } from '@prisma/client'

let prisma: PrismaClient
declare global {
  var __db: PrismaClient | undefined
}

if (process.env.NODE_ENV === 'production') {
  prisma = new PrismaClient()
  prisma.$connect()
} else {
  if (!global.__db) {
    global.__db = new PrismaClient()
    global.__db.$connect()
  }
  prisma = global.__db
}

export { prisma }

위 설정은 prisma/client인스턴스를 생성하고 개발 중에 라이브 다시 로드로 인해 데이터베이스가 연결로 가득 차는 것을 방지하기 위한 예방 조치가 있습니다.

profile
이유를 생각하는 개발자

0개의 댓글