Skip to content

Commit 9bc70d5

Browse files
authored
Merge pull request #143 from devping-kr/THKV-147
Feat[THKV-147] 구글 로그인 구현
2 parents ee99d32 + 614898a commit 9bc70d5

7 files changed

Lines changed: 84 additions & 5 deletions

File tree

src/api/auth/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { post } from '@/lib/axios';
22
import { env } from '@/lib/env';
33
import {
4+
GoogleLoginRequest,
45
LoginRequest,
56
SendRequest,
67
SignupRequest,
@@ -41,9 +42,18 @@ const login = async (request: LoginRequest): Promise<Result<LoginResponse>> => {
4142
return result;
4243
};
4344

45+
const googleLogin = async (request: GoogleLoginRequest) => {
46+
const response = await post<Result<LoginResponse>>(
47+
AUTH_API.GOOGLELOGIN,
48+
request,
49+
);
50+
return response.data;
51+
};
52+
4453
export const auth = {
4554
signUp,
4655
verifySend,
4756
verifyConfirm,
4857
login,
58+
googleLogin,
4959
};

src/app/(auth)/login/page.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
'use client';
22

3+
import { Suspense } from 'react';
34
import Login from '@/components/feature/Login';
45

56
const page = () => {
6-
return <Login />;
7+
return (
8+
<Suspense fallback={<div></div>}>
9+
<Login />
10+
</Suspense>
11+
);
712
};
813

914
export default page;

src/components/shared/Auth/LoginBody/index.tsx

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
'use client';
22

3-
import { useState } from 'react';
3+
import { useSearchParams } from 'next/navigation';
4+
import { useEffect, useState } from 'react';
5+
import { env } from '@/lib/env';
46
import { zodResolver } from '@hookform/resolvers/zod';
57
import { SubmitHandler, useForm } from 'react-hook-form';
68
import { loginSchema } from '@/schema/authSchema';
79
import { LoginRequest } from '@/type/auth/authRequest';
10+
import { saveTokens } from '@/utils/saveTokens';
811
import Button from '@/components/common/Button/Button';
912
import Icon from '@/components/common/Icon';
1013
import { Input } from '@/components/common/Input';
@@ -16,6 +19,7 @@ import {
1619
Subtitle2Black,
1720
} from '@/components/common/Typography';
1821
import { BASE_ROUTES } from '@/constants/_navbar';
22+
import { usePostGoogleLogin } from '@/hooks/auth/usePostGoogleLogin';
1923
import { usePostLogin } from '@/hooks/auth/usePostLogin';
2024
import { useAuth } from '@/hooks/useAuth';
2125
import useNavigate from '@/hooks/useNavigate';
@@ -24,12 +28,17 @@ import { useUserStore } from '@/stores/useUserStore';
2428

2529
const LoginBody = () => {
2630
const { navigate } = useNavigate();
27-
const [isShowPassword, setIsShowPassword] = useState(false);
28-
const { mutate: loginMutate } = usePostLogin();
2931
const { login } = useAuth();
32+
const searchParams = useSearchParams();
33+
34+
const [isShowPassword, setIsShowPassword] = useState(false);
35+
3036
const showToast = useToastStore((set) => set.showToast);
3137
const setUserInfo = useUserStore((set) => set.setUserInfo);
3238

39+
const { mutate: loginMutate } = usePostLogin();
40+
const { mutate: googleLoginMutate } = usePostGoogleLogin();
41+
3342
const {
3443
register,
3544
handleSubmit,
@@ -52,12 +61,40 @@ const LoginBody = () => {
5261
login();
5362
},
5463
onError: (error) => {
55-
error.message;
5664
showToast(`${error.message} 로그인 실패`, 'warning', 1000);
5765
},
5866
});
5967
};
6068

69+
const googleLoginHandler = () => {
70+
navigate(
71+
`https://accounts.google.com/o/oauth2/v2/auth?client_id=${env.GOOGLE_CLIENT_ID}&redirect_uri=${env.GOOGLE_REDIRECT_URL}&response_type=code&scope=email%20profile%20openid&access_type=offline`,
72+
);
73+
};
74+
75+
useEffect(() => {
76+
const authCode = searchParams.get('code');
77+
if (authCode) {
78+
googleLoginMutate(
79+
{ authCode: authCode || '' },
80+
{
81+
onSuccess: (data) => {
82+
const { username, userId, email } = data.data;
83+
setUserInfo(username, userId, email);
84+
login();
85+
saveTokens({
86+
accessToken: data.data.accessToken,
87+
refreshToken: data.data.refreshToken,
88+
});
89+
},
90+
onError: () => {
91+
showToast('구글 로그인 실패', 'warning', 1000);
92+
},
93+
},
94+
);
95+
}
96+
}, [searchParams]);
97+
6198
return (
6299
<div className='flex w-[480px] flex-col items-center gap-10'>
63100
<form onSubmit={handleSubmit(onSubmit)} className='w-full'>
@@ -131,6 +168,7 @@ const LoginBody = () => {
131168
width='full'
132169
size='md'
133170
variant='outline'
171+
onClick={() => googleLoginHandler()}
134172
>
135173
<Icon name='google' width={24} height={24} />
136174
<Subtitle2Black>구글로 시작하기</Subtitle2Black>

src/constants/_apiPath.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const AUTH_API = {
2020
LOGIN: `${BASE_API.AUTHS}/login`,
2121
REISSUE: `${BASE_API.AUTHS}/reissue`,
2222
LOGOUT: `${BASE_API.AUTHS}/logout`,
23+
GOOGLELOGIN: `${BASE_API.AUTHS}/oauth2/google`,
2324
};
2425

2526
/**
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { useMutation, UseMutationOptions } from '@tanstack/react-query';
2+
import { AxiosError } from 'axios';
3+
import { auth } from '@/api/auth';
4+
import { GoogleLoginRequest } from '@/type/auth/authRequest';
5+
import { LoginResponse } from '@/type/auth/authResponse';
6+
import { Result } from '@/type/response';
7+
8+
export const usePostGoogleLogin = (
9+
options?: UseMutationOptions<
10+
Result<LoginResponse>,
11+
AxiosError<Result<string>>,
12+
GoogleLoginRequest
13+
>,
14+
) => {
15+
return useMutation({
16+
mutationFn: (request) => auth.googleLogin(request),
17+
...options,
18+
});
19+
};

src/lib/env.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ export const env = Object.freeze({
33
QR_API_URL: `${process.env.NEXT_PUBLIC_QR_API_URL}`,
44
QR_APP_KEY: `${process.env.NEXT_PUBLIC_QR_APPKEY}`,
55
GA_ID: process.env.NEXT_PUBLIC_GA_ID,
6+
GOOGLE_CLIENT_ID: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID,
7+
GOOGLE_REDIRECT_URL: process.env.NEXT_PUBLIC_GOOGLE_REDIRECT_URL,
68
});

src/type/auth/authRequest.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@ export interface VerifyRequest {
2020
email: string;
2121
verifyCode: string;
2222
}
23+
24+
export interface GoogleLoginRequest {
25+
authCode: string;
26+
}

0 commit comments

Comments
 (0)