NextAuth에서 에러 핸들링을 한 경험을 공유하기 위해 이 글을 작성한다.
NextAuth를 보통 소셜로그인 용도와 이메일 비밀번호 로그인만 진행하고, 에러핸들링을 하는 포스트를 생각보다 찾기 힘들었어서 나의 에러핸들링 경험을 공유 할 것이다.
우선 Next.js Route handlers에서 유저의 정보를 제대로 받아오지 못했었다.
// api/auth/[...nextauth]/route.ts
async authorize(credentials) {
if (!credentials) {
throw new Error('입력 값이 잘못되었습니다.');
}
// supabase에서 데이터 가져와서 객체를 만든 후 return
const { password } = credentials;
const companyUser = await supabase
.from('company_user')
.select('id, email, name, password, role')
.eq('email', `${credentials?.email}`)
.single();
const userData = companyUser.data;
if (userData) {
const result = await bcrypt.compareSync(
password,
userData?.password as string,
);
if (!result) {
return null;
}
}
return userData;
},
authorize 안에서 userData값을 return 해주었다.
// api/auth/signup/route.ts
import { CompanyUserSignUpType } from '@/types/auth';
import bcrypt from 'bcrypt';
import { NextRequest, NextResponse } from 'next/server';
import { supabase } from '../../db';
export const POST = async (req: NextRequest) => {
const userData = await req.json();
const { data } = await supabase
.from('company_user')
.select('email')
.eq('email', userData.email)
.single();
if (data) {
return NextResponse.json({
status: 409,
message: '이미 가입되어있는 이메일 입니다!',
});
}
const hashedPassword = await bcrypt.hashSync(userData.password, 5);
const { error: saveError } = await supabase
.from('company_user')
.insert<Omit<CompanyUserSignUpType, 'confirmPassword'>>({
...userData,
password: hashedPassword,
});
if (saveError) {
return NextResponse.json({
status: saveError.code,
message: '회원가입에 실패하였습니다!',
});
}
return NextResponse.json({ status: 200, message: '회원가입 완료!' });
};
Request가 클라이언트로부터 들어오면 해당되는 status, message로 구성된 객체를 Response로 반환하였다.
const onSubmit = async (data: CompanyUserSignUpType) => {
const userData = {
email: data.email,
name: data.name,
password: data.password,
};
const res = await fetch('/api/auth/signup', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData),
});
const message = await res.json();
if (message.status === 409) {
toast.error(message.message);
}
if (message.status === 200) {
toast.success(message.message);
router.push('/auth/signin');
}
};
onSubmit 함수를 통해 Route handlers의 주소로 요청을 보내고 이 요청을 받아 toast로 출력해주었다.