Skip to content

Commit

Permalink
FE-29 🔀 로그인, 간편 로그인 수정 사항 반영 요청 (#140)
Browse files Browse the repository at this point in the history
* ✨ 네이버 post api 추가

* ✨ 구글 post api 추가

* 🔧 라우팅 수정

* ✨ 네이버 로그인 훅 추가 및 라우팅, 에러 핸들링 구현

* ✨ 구글 로그인 훅 추가 및 라우팅, 에러 핸들링 구현

* ✨ 네이버 간편 로그인 리다이렉트 설정

* ✨ 구글 간편 로그인 리다이렉트 설정

* 🔧 환경 변수 적용: 네이버, 구글, 카카오 로그인 URL 업데이트

* 🔧 가입하기 경로 수정

* 🔧 로그인 훅 라우팅 수정

* 🔧 로그인 훅 에러처리 로직 수정
  • Loading branch information
jangmoonwon authored Aug 1, 2024
1 parent c74c7dd commit f16b7e8
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 9 deletions.
11 changes: 11 additions & 0 deletions src/apis/postGoogleOauth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import httpClient from '.';

const postGoogleOauth = async (code: string) => {
const response = await httpClient.post('/auth/signIn/GOOGLE', {
redirectUri: process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URI,
token: code,
});
return response.data;
};

export default postGoogleOauth;
12 changes: 12 additions & 0 deletions src/apis/postNaverOauth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import httpClient from '.';

const postNaverOauth = async (code: string, state: string) => {
const response = await httpClient.post('/auth/signIn/NAVER', {
state,
redirectUri: process.env.NEXT_PUBLIC_NAVER_REDIRECT_URI,
token: code,
});
return response.data;
};

export default postNaverOauth;
41 changes: 41 additions & 0 deletions src/hooks/useGoogleLogin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import postGoogleOauth from '@/apis/postGoogleOauth';
import { toast } from '@/components/ui/use-toast';
import { useMutation } from '@tanstack/react-query';
import { isAxiosError } from 'axios';
import { useRouter } from 'next/router';

const useGoogleLogin = () => {
const router = useRouter();

return useMutation({
mutationFn: async (code: string) => {
const result = await postGoogleOauth(code);
localStorage.setItem('accessToken', result.accessToken);
localStorage.setItem('refreshToken', result.refreshToken);
return result;
},
onSuccess: () => {
router.push('/epigrams');
},
onError: (error) => {
if (isAxiosError(error)) {
const status = error.response?.status;

if (!status) return;

if (status === 400) {
toast({ description: '잘못된 요청입니다. 요청을 확인해 주세요.', className: 'bg-state-error text-white font-semibold' });
router.push('/auth/SignIn');
return;
}

if (status >= 500) {
toast({ description: '서버에 문제가 발생했습니다. 잠시 후 다시 시도해 주세요.', className: 'bg-state-error text-white font-semibold' });
}
}
toast({ description: '알 수 없는 에러가 발생했습니다.', className: 'bg-state-error text-white font-semibold' });
},
});
};

export default useGoogleLogin;
2 changes: 1 addition & 1 deletion src/hooks/useKakaoLogin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const useKakaoLogin = () => {
return result;
},
onSuccess: () => {
router.push('/');
router.push('/epigrams');
},
onError: (error) => {
if (isAxiosError(error)) {
Expand Down
42 changes: 42 additions & 0 deletions src/hooks/useNaverLogin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import postNaverOauth from '@/apis/postNaverOauth';
import { toast } from '@/components/ui/use-toast';
import { useMutation } from '@tanstack/react-query';
import { isAxiosError } from 'axios';
import { useRouter } from 'next/router';

const useNaverLogin = () => {
const router = useRouter();

return useMutation({
mutationFn: async ({ code, state }: { code: string; state: string }) => {
const result = await postNaverOauth(code, state);
localStorage.setItem('accessToken', result.accessToken);
localStorage.setItem('refreshToken', result.refreshToken);
return result;
},
onSuccess: () => {
router.push('/epigrams');
},
onError: (error) => {
if (isAxiosError(error)) {
const status = error.response?.status;

if (!status) return;

if (status === 400) {
toast({ description: '잘못된 요청입니다. 요청을 확인해 주세요.', className: 'bg-state-error text-white font-semibold' });
router.push('/auth/SignIn');
return;
}

if (status >= 500) {
toast({ description: '서버에 문제가 발생했습니다. 잠시 후 다시 시도해 주세요.', className: 'bg-state-error text-white font-semibold' });
}
}

toast({ description: '알 수 없는 에러가 발생했습니다.', className: 'bg-state-error text-white font-semibold' });
},
});
};

export default useNaverLogin;
33 changes: 30 additions & 3 deletions src/hooks/useSignInMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { postSignin } from '@/apis/auth';
import { toast } from '@/components/ui/use-toast';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import { isAxiosError } from 'axios';

const useSigninMutation = () => {
const router = useRouter();
Expand All @@ -11,10 +12,36 @@ const useSigninMutation = () => {
onSuccess: (data) => {
localStorage.setItem('accessToken', data.accessToken);
localStorage.setItem('refreshToken', data.refreshToken);
router.push('/');
router.push('/epigrams');
},
onError: () => {
toast({ description: '이메일 혹은 비밀번호를 확인해주세요.', className: 'border-state-error text-state-error font-semibold' });
onError: (error) => {
if (!isAxiosError(error)) {
return;
}

const { status } = error.response || {};

if (status === 500) {
toast({
description: '서버 오류가 발생했습니다. 잠시 후 다시 시도해주세요.',
className: 'border-state-error text-state-error font-semibold',
});
return;
}

// NOTE: status값은 항상 있으며 undefined와 숫자를 비교연산 할 수 없어 Number로 설정
if (Number(status) >= 500) {
toast({
description: '서버에서 예상치 못한 문제가 발생했습니다. 잠시 후 다시 시도해주세요.',
className: 'border-state-error text-state-error font-semibold',
});
return;
}

toast({
description: '이메일 혹은 비밀번호를 확인해주세요.',
className: 'border-state-error text-state-error font-semibold',
});
},
});
};
Expand Down
15 changes: 10 additions & 5 deletions src/pages/auth/SignIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,24 @@ export default function SignIn() {
</Form>
<div className=' flex justify-end items-center gap-2 w-full lg:max-w-[640px] md:max-w-[384px] md:px-0 px-6 md:mb-[60px] mb-[50px]'>
<h2 className=' text-blue-400 lg:text-xl md:text-base sm:text-sm'>회원이 아니신가요?</h2>
<Link href='/'>
<Link href='/auth/SignUp'>
<Button type='button' variant='link' className='lg:text-xl md:text-base sm:text-sm p-0 underline'>
가입하기
</Button>
</Link>
</div>
<div className='flex gap-4'>
<Link href={`https://nid.naver.com/oauth2.0/authorize?client_id=${process.env.NEXT_PUBLIC_NAVER_CLIENT_ID}&redirect_uri=http://localhost:3000&response_type=code`}>
<Link
href={`https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id=${process.env.NEXT_PUBLIC_NAVER_CLIENT_ID}&state=${'test'}&redirect_uri=${process.env.NEXT_PUBLIC_NAVER_REDIRECT_URI}`}
>
<Image src='/logo-naver.svg' alt='logo-naver' width={60} height={60} className='md:size-[60px] size-10' />
</Link>
<Link href={`https://accounts.google.com/o/oauth2/v2/auth?client_id=${process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID}&redirect_uri=http://localhost:3000&response_type=code&scope=email%20profile`}>
<Image src='/logo-google.svg' alt='logo-google' width={60} height={60} className='md:size-[60px] size-10' />
</Link>
{/* // FIXME: 구글 간편 로그인 리다이렉트시 500에러가 발생하는 부분으로 주석 처리하였음 */}
{/* <Link
href={`https://accounts.google.com/o/oauth2/v2/auth?client_id=${process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID}&redirect_uri=${process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URI}&response_type=code&scope=email%20profile`}
> */}
<Image src='/logo-google.svg' alt='logo-google' width={60} height={60} className='md:size-[60px] size-10' />
{/* </Link> */}
<Link href={`https://kauth.kakao.com/oauth/authorize?client_id=${process.env.NEXT_PUBLIC_KAKAO_CLIENT_ID}&redirect_uri=${process.env.NEXT_PUBLIC_REDIRECT_URI}&response_type=code`}>
<Image src='/logo-kakao.svg' alt='logo-kakao' width={60} height={60} className='md:size-[60px] size-10' />
</Link>
Expand Down
21 changes: 21 additions & 0 deletions src/pages/auth/redirect/google-callback/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useEffect } from 'react';
import { useSearchParams } from 'next/navigation';
import useGoogleLogin from '@/hooks/useGoogleLogin';

export default function Google() {
const searchParams = useSearchParams();
const code = searchParams.get('code');
const { mutate: login } = useGoogleLogin();

useEffect(() => {
if (code) {
login(code);
} else {
/* eslint-disable no-console */
console.log(code); // code가 없을 때 콘솔에 출력
}
}, [code, login]);
}

// code가 없는 경우의 예시 http://localhost:3000/auth/redirect/kakao
// 토스트로 에러 메시지 띄우고, 로그인 페이지로 리다이렉트
19 changes: 19 additions & 0 deletions src/pages/auth/redirect/naver/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import useNaverLogin from '@/hooks/useNaverLogin';
import { useSearchParams } from 'next/navigation';
import { useEffect } from 'react';

export default function Naver() {
const searchParams = useSearchParams();
const code = searchParams.get('code');
const state = searchParams.get('state');
const { mutate: login } = useNaverLogin();

useEffect(() => {
if (code && state) {
login({ code, state });
} else {
/* eslint-disable no-console */
console.log(code, state); // code가 없을 때 콘솔에 출력
}
}, [code, state, login]);
}

0 comments on commit f16b7e8

Please sign in to comment.