Skip to content
2 changes: 1 addition & 1 deletion src/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ export const checkToken = (): Promise<AccessTokenResponse> => {
};

export const signInKakao = (data: KakakoSignInRequest): Promise<KakakoSignInResponse> => {
return apiClient.post(`/${process.env.NEXT_PUBLIC_TEAM}/auth/signIn/KAKAO`, data);
return apiClient.post(`${process.env.NEXT_PUBLIC_API_URL}/api/auth/signIn/KAKAO`, data);
};
1 change: 0 additions & 1 deletion src/pages/api/auth/check-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { parseCookie } from '@/lib/cookie';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const cookieHeader = req.headers.cookie;
console.log('test');
if (cookieHeader) {
const cookies = parseCookie(cookieHeader);

Expand Down
28 changes: 28 additions & 0 deletions src/pages/api/auth/signIn/KAKAO.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { AxiosError } from 'axios';
import { NextApiRequest, NextApiResponse } from 'next';

import apiClient from '@/api/apiClient';
import { setAuthCookies } from '@/lib/cookie';
import { KakakoSignInResponse } from '@/types/AuthTypes';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const url = `/${process.env.NEXT_PUBLIC_TEAM}/auth/signIn/KAKAO`;
const data = (await apiClient.post(url, req.body)) as KakakoSignInResponse;
const { accessToken, refreshToken } = data;
setAuthCookies(res, accessToken, refreshToken);

res.status(200).json({
user: data.user,
message: '로그인이 성공했습니다',
success: true,
});
res.end();
} catch (error) {
const err = error as AxiosError;
const message = error instanceof AxiosError ? error.message : '서버 오류가 발생했습니다.';
const status = err.response?.status || 500;

res.status(status).json({ message });
}
}
File renamed without changes.
68 changes: 48 additions & 20 deletions src/pages/oauth/signup/kakao.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,78 @@
import { useEffect } from 'react';

import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
import { useRouter } from 'next/router';

import { signInKakao } from '@/api/auth';
import { getUser } from '@/api/user';
import ErrorModal from '@/components/common/Modal/ErrorModal';
import useErrorModal from '@/hooks/useErrorModal';
import { KakakoSignInRequest, KakakoSignInResponse } from '@/types/AuthTypes';
import { useUser } from '@/hooks/useUser';

/* 카카오 로그인 버튼 클릭 시 API 호출하여 로그인/회원가입 처리 */
const KakaoLoginCallbackPage = () => {
const { setUser } = useUser();
const router = useRouter();
const { code } = router.query;

const { open, setOpen, handleError, errorMessage } = useErrorModal();

/* 카카오 회원가입/로그인 요청 */
const handleKakaoAuth = async (): Promise<KakakoSignInResponse> => {
const params: KakakoSignInRequest = {
state: '',
redirectUri: process.env.NEXT_PUBLIC_KAKAO_REDIRECT_URI ?? '',
token: code as string,
};
return await signInKakao(params);
};
const params =
typeof code === 'string'
? {
state: '',
redirectUri: process.env.NEXT_PUBLIC_KAKAO_REDIRECT_URI ?? '',
token: code,
}
: undefined;

const { data, error } = useQuery({
queryKey: ['handleKakaoAuth'],
queryFn: handleKakaoAuth,
enabled: typeof code === 'string',
queryFn: async () => {
if (!params) return;
return await signInKakao(params);
},
enabled: !!params,
retry: false,
});

const { refetch: userRefecth } = useQuery({
queryKey: ['getUser'],
queryFn: getUser,
enabled: false,
retry: false,
});

useEffect(() => {
/* API 에러 시 모달로 에러 출력 */
if (!data) return;

/* API 성공 시 전역 유저 데이터 세팅 */
const setUserData = async () => {
try {
const { data: userData } = await userRefecth();
if (!userData) return;

setUser(userData);
router.push('/');
} catch (error) {
if (axios.isAxiosError(error) && error.response) {
// 유저 정보 API 에러를 모달로 출력
handleError(error.response?.data as Error);
}
}
};

setUserData();
}, [data, router, setUser, userRefecth, handleError]);

useEffect(() => {
/* 카카오 API 에러 시 모달로 에러 출력 */
if (error) {
handleError(new Error('카카오 로그인을 재시도해주세요'));
}

/* API 성공 시 로그인 처리 */
if (data) {
localStorage.setItem('accessToken', data.accessToken);
localStorage.setItem('refreshToken', data.refreshToken);
router.replace('/');
}
}, [data, error, router, code, handleError]);
}, [error, handleError]);

return (
/* 에러 모달에서 확인 버튼 클릭 시 로그인 화면으로 리디렉트 처리 */
Expand Down
2 changes: 1 addition & 1 deletion src/pages/signin/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const SignIn = () => {
{/* 폼 시작 */}
<FormProvider {...methods}>
<form onSubmit={handleSubmit(handleOnClickLogin)}>
<div className='flex flex-col items-center gap-4 md:gap-9'>
<div className='flex flex-col items-center gap-9 md:gap-9'>
{/* 이메일 */}
<div className='flex flex-col gap-2.5'>
<label htmlFor='email'>이메일</label>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/signup/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const Signup = () => {
loginMutation.mutate({ email, password });
},
onError: (error) => {
if (error.response?.status === 400) {
if (error.response?.status === 500) {
// 로그인 오류인 경우 공통 에러 메시지
setError('root', { message: '닉네임이 중복되었습니다.' });
} else {
Expand Down Expand Up @@ -131,7 +131,7 @@ const Signup = () => {
{/* 폼 시작 */}
<FormProvider {...methods}>
<form onSubmit={handleSubmit(handleOnClickSignup)}>
<div className='flex flex-col items-center gap-4 md:gap-9'>
<div className='flex flex-col items-center gap-9 md:gap-9'>
{/* 이메일 */}
<div className='flex flex-col gap-2.5'>
<label htmlFor='email'>이메일</label>
Expand Down