diff --git a/src/apis/auth.ts b/src/apis/auth.ts index e13efb7d..a0c8c36b 100644 --- a/src/apis/auth.ts +++ b/src/apis/auth.ts @@ -1,4 +1,4 @@ -import type { PostSigninRequestType, PostSigninResponseType, PostSignUpRequestType, PostSignUpResponseType } from '@/schema/auth'; +import type { PostRefreshTokenRequestType, PostRefreshTokenResponseType, PostSigninRequestType, PostSigninResponseType, PostSignUpRequestType, PostSignUpResponseType } from '@/schema/auth'; import httpClient from '.'; export const postSignin = async (request: PostSigninRequestType): Promise => { @@ -10,3 +10,8 @@ export const postSignup = async (request: PostSignUpRequestType): Promise => { + const response = await httpClient.post('/auth/refresh-token', request); + return response.data; +}; diff --git a/src/hooks/useRefreshToken.ts b/src/hooks/useRefreshToken.ts new file mode 100644 index 00000000..a4377665 --- /dev/null +++ b/src/hooks/useRefreshToken.ts @@ -0,0 +1,16 @@ +import { useMutation } from '@tanstack/react-query'; +import { postRefreshToken } from '@/apis/auth'; +import { PostRefreshTokenRequestType, PostRefreshTokenResponseType } from '@/schema/auth'; + +const useRefreshToken = () => + useMutation({ + mutationFn: postRefreshToken, + onSuccess: (data) => { + localStorage.setItem('accessToken', data.accessToken); + }, + onError: () => { + localStorage.removeItem('refreshToken'); + }, + }); + +export default useRefreshToken; diff --git a/src/pages/auth/SignIn.tsx b/src/pages/auth/SignIn.tsx index 7c297ab6..7e4af11c 100644 --- a/src/pages/auth/SignIn.tsx +++ b/src/pages/auth/SignIn.tsx @@ -9,17 +9,21 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { Form, FormControl, FormField, FormItem, FormMessage } from '@/components/ui/form'; import { PostSigninRequest, PostSigninRequestType } from '@/schema/auth'; import useSigninMutation from '@/hooks/useSignInMutation'; +import useRefreshToken from '@/hooks/useRefreshToken'; export default function SignIn() { const mutationSignin = useSigninMutation(); + const { mutate: refreshAccessToken } = useRefreshToken(); const router = useRouter(); useEffect(() => { - const accessToken = localStorage.getItem('accessToken'); - if (accessToken) { + const refreshToken = typeof window !== 'undefined' ? localStorage.getItem('refreshToken') : null; + + if (refreshToken) { + refreshAccessToken({ refreshToken }); router.push('/epigrams'); } - }, [router]); + }, [refreshAccessToken]); // 폼 정의 const form = useForm({ diff --git a/src/pages/auth/SignUp.tsx b/src/pages/auth/SignUp.tsx index bd21425c..37a829fa 100644 --- a/src/pages/auth/SignUp.tsx +++ b/src/pages/auth/SignUp.tsx @@ -9,17 +9,21 @@ import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'; import useRegisterMutation from '@/hooks/useRegisterMutation'; +import useRefreshToken from '@/hooks/useRefreshToken'; export default function SignUp() { const [focusedField, setFocusedField] = useState(null); + const { mutate: refreshAccessToken } = useRefreshToken(); const router = useRouter(); useEffect(() => { - const accessToken = localStorage.getItem('accessToken'); - if (accessToken) { + const refreshToken = typeof window !== 'undefined' ? localStorage.getItem('refreshToken') : null; + + if (refreshToken) { + refreshAccessToken({ refreshToken }); router.push('/epigrams'); } - }, [router]); + }, [refreshAccessToken]); const form = useForm({ resolver: zodResolver(PostSignUpRequest), diff --git a/src/schema/auth.ts b/src/schema/auth.ts index c5a4ee7e..c5154033 100644 --- a/src/schema/auth.ts +++ b/src/schema/auth.ts @@ -41,9 +41,20 @@ export const PostAuthResponse = z.object({ user: User, }); +export const PostRefreshTokenRequest = z.object({ + refreshToken: z.string(), +}); + +export const PostRefreshTokenResponse = z.object({ + accessToken: z.string(), +}); + // NOTE: 회원가입 타입 export type PostSignUpRequestType = z.infer; export type PostSignUpResponseType = z.infer; // NOTE: 로그인 타입 export type PostSigninRequestType = z.infer; export type PostSigninResponseType = z.infer; +// NOTE: 리프레시 토큰 +export type PostRefreshTokenRequestType = z.infer; +export type PostRefreshTokenResponseType = z.infer;