Auth.js Credential 회원가입 구현하기

no-pla·2024년 2월 19일
0

TIL

목록 보기
4/8
post-thumbnail

Auth.js(Next-Auth)를 사용하여 이메일/비밀번호로 회원가입을 구현해 보자.

Auth.js와 더불어 mongoDB를 사용할 것이기 때문에 prisma도 함께 설치해 준다.

  1. 설치
  1. SessionProvider 설정하기
    Provider는 클라이언트 컴포넌트로 설정해야하기 때문에 따로 Provider를 만들어 layout.tsx의 body를 감싸준다.
"use client";

import React from "react";
import { SessionProvider } from "next-auth/react";
import { RecoilRoot } from "recoil";

const Providers = ({ children, session }: any) => {
  return (
    <RecoilRoot>
      <SessionProvider session={session}>{children}</SessionProvider>
    </RecoilRoot>
  );
};

export default Providers;
  1. route.js|ts 파일 생성
    API route를 사용할 것이기 때문에 api/register/route.js를 생성해 준다. Next.js 13 부터는 handler가 아닌 메서드 명으로 함수를 생성해 주어야 한다.

api/register/route.js

import { NextResponse } from "next/server";

export async function POST(req) {
const { email, password, name } = await req.json();

return null;

}

회원 가입 시에 이메일, 비밀번호와 닉네임도 받아온다. 클라이언트 쪽에서 유효성 검사를 하지만, 사용자가 임의로 해당 기능을 해제했을 등의 상황에 대비하여 서버 측에서도 검사를 진행하는 편이 좋다고 한다.

따라서 세 필드가 비어있는지를 확인하는 로직을 추가해 준다.

api/register/route.js

import { NextResponse } from "next/server";

export async function POST(req) {
  const { email, password, name } = await req.json();

  if (!email || !password || !name) {
    return NextResponse.json({
      message: "이메일이나 비밀번호, 닉네임이 비어 있습니다.",
      ok: false,
    });
  }

  return null;
}

다음으로 유저가 이미 가입했는지를 prisma.user.findUnique를 사용해 검사한다.

import { NextResponse } from "next/server";

const prisma = new PrismaClient(); // ! PrismaClient를 추가해 준다.

export async function POST(req) {
  const { email, password, name } = await req.json();

  // 아이디 비밀번호 닉네임 전부 존재 확인
  if (!email || !password || !name) {
    return NextResponse.json({
      message: "이메일이나 비밀번호, 닉네임이 비어 있습니다.",
      ok: false,
    });
  }

  // 이미 가입한 유저인지 확인
  const exist = await prisma.user.findUnique({
    where: {
      email,
    },
  });

  if (exist) {
    return NextResponse.json({
      message: "이미 가입된 유저입니다.",
      ok: false,
    });
  }

  return null;
}

이메일, 비밀번호, 닉네임이 모두 존재하고, 가입되지 않은 유저라면 가입을 진행한다. 이 때 비밀번호를 DB에 저장할 때는 보안을 위해 암호화해야 한다. 이를 위해 bcrypt라이브러리를 사용했다.

import { PrismaClient } from "@prisma/client";
import { NextResponse } from "next/server";
import bcrypt from "bcrypt";

const prisma = new PrismaClient();

export async function POST(req) {
  const { email, password, name } = await req.json();
  // 아이디 비밀번호 닉네임 전부 존재 확인
  if (!email || !password || !name) {
    return NextResponse.json({
      message: "이메일이나 비밀번호, 닉네임이 비어 있습니다.",
      ok: false,
    });
  }

  // 이미 가입한 유저인지 확인
  const exist = await prisma.user.findUnique({
    where: {
      email,
    },
  });

  if (exist) {
    return NextResponse.json({
      message: "이미 가입된 유저입니다.",
      ok: false,
    });
  }
  // 가입 로직 작성
  const hashedPassword = await bcrypt.hash(password, 10);

  const user = await prisma.user.create({
    data: {
      email,
      password: hashedPassword,
      name,
      image:
        "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png", // TODO: 임시 빈 프로필 사진. 추후 수정
    },
  });

  return NextResponse.json(user);
}

이대로 모든 검사를 통과하면 정상적으로 유저 정보가 DB에 저장된다.

클라이언트 측에서 유저 정보에 접근하기 위해서는 useSession 훅을 사용하면 접근할 수 있다.

  const { data: session } = useSession({
    required: true,
    onUnauthenticated() {
      router.push("/login");
    },
  });

useSessiononUnauthenticated를 사용하면 특정 페이지에 로그아웃 상태로 접근했을 때의 경우를 처리해 줄 수 있다.

0개의 댓글