Skip to content

Commit 31ab606

Browse files
committed
✨feat(#163): google login 구현
1 parent 11f8908 commit 31ab606

2 files changed

Lines changed: 103 additions & 57 deletions

File tree

src/app/login/auth/page.tsx

Lines changed: 86 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ const Auth = () => {
1717
const [absoluteUrl, setAbsoluteUrl] = useState('');
1818
const [storeUrl, setstoreUrl] = useState('');
1919
const [type, setType] = useState('');
20+
const [oauthAccessToken, setOauthAccessToken] = useState('');
21+
const [provider, setProvider] = useState('');
2022

2123
useEffect(() => {
2224
if (typeof window !== 'undefined') {
25+
//oauth 타입을 state에 저장
2326
const params = new URL(window.location.href).searchParams;
2427
const typeParam = params.get('type');
2528
setType(typeParam);
@@ -31,79 +34,119 @@ const Auth = () => {
3134
}, []);
3235

3336
useEffect(() => {
34-
if (!absoluteUrl) {
35-
return;
36-
}
37+
if (!absoluteUrl || !type) return;
3738
const getToken = async () => {
3839
const AUTHORIZATION_CODE = new URL(window.location.href).searchParams.get(
3940
'code'
4041
);
42+
4143
const TYPE = new URL(window.location.href).searchParams.get('type');
4244

4345
let tokenUrl = '';
44-
let provider: 'KAKAO' | 'GOOGLE' | 'NAVER';
4546

4647
if (!AUTHORIZATION_CODE || !TYPE) {
4748
console.error('Authorization Code or Type is missing');
4849
return;
4950
}
5051

52+
//type에 따라 다른 토큰 url 지정
5153
switch (TYPE) {
5254
case 'kakao':
53-
tokenUrl = `https://kauth.kakao.com/oauth/token?grant_type=authorization_code&client_id=${REST_API_KEY}&redirect_uri=${absoluteUrl}&code=${AUTHORIZATION_CODE}`;
54-
provider = 'KAKAO';
55+
setProvider('KAKAO');
56+
try {
57+
const response = await axios.post(
58+
'https://kauth.kakao.com/oauth/token',
59+
new URLSearchParams({
60+
grant_type: 'authorization_code',
61+
client_id: REST_API_KEY,
62+
redirect_uri: absoluteUrl,
63+
code: AUTHORIZATION_CODE
64+
}),
65+
{
66+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
67+
}
68+
);
69+
setOauthAccessToken(response.data.access_token);
70+
} catch (error) {
71+
console.error(error);
72+
clearLetterUrl();
73+
return;
74+
}
75+
5576
break;
5677
case 'google':
78+
setProvider('GOOGLE');
79+
try {
80+
const body = new URLSearchParams({
81+
grant_type: 'authorization_code',
82+
client_id: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID!,
83+
client_secret: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_SECRET!,
84+
redirect_uri: absoluteUrl,
85+
code: AUTHORIZATION_CODE
86+
});
87+
88+
const response = await axios.post(
89+
'https://oauth2.googleapis.com/token',
90+
body.toString(),
91+
{
92+
headers: {
93+
'Content-Type': 'application/x-www-form-urlencoded'
94+
}
95+
}
96+
);
97+
setOauthAccessToken(response.data.access_token);
98+
} catch (error) {
99+
console.error('Unsupported OAuth type:', type);
100+
clearLetterUrl();
101+
return;
102+
}
57103
break;
58104
case 'naver':
59105
break;
60106
default:
61107
console.error('Unknown OAuth type:', TYPE);
62108
return;
63109
}
110+
};
111+
getToken();
112+
}, [absoluteUrl, type]);
64113

65-
try {
66-
const response = await axios.post(tokenUrl, {
67-
headers: { 'Content-Type': 'application/json' }
68-
});
69-
70-
const oauthAccessToken = response.data.access_token;
71-
72-
if (oauthAccessToken) {
73-
login(provider, oauthAccessToken)
74-
.then((res) => {
75-
console.log('accessToken', res.data.accessToken);
76-
setTokens(res.data.accessToken, res.data.refreshToken);
77-
/* 온보딩 여부 저장 */
78-
setOnboarding(res.data.isProcessedOnboarding);
114+
useEffect(() => {
115+
try {
116+
if (oauthAccessToken) {
117+
login(provider, oauthAccessToken)
118+
.then((res) => {
119+
console.log('accessToken', res.data.accessToken);
120+
setTokens(res.data.accessToken, res.data.refreshToken);
121+
/* 온보딩 여부 저장 */
122+
setOnboarding(res.data.isProcessedOnboarding);
123+
if (storeUrl) {
124+
router.push(`/verify/letter?url=${storeUrl}`);
125+
clearLetterUrl();
126+
} else {
127+
router.push('/planet');
128+
}
129+
})
130+
.catch((error) => {
131+
if (error.response && error.response.status === 401) {
132+
console.log('registerToken', error.response.data.registerToken);
133+
setRegisterToken(error.response.data.registerToken);
79134
if (storeUrl) {
80-
router.push(`/verify/letter?url=${storeUrl}`);
135+
router.push(`/signup/step1?url=${storeUrl}`);
81136
clearLetterUrl();
82137
} else {
83-
router.push('/planet');
138+
router.push('/signup/step1');
84139
}
85-
})
86-
.catch((error) => {
87-
if (error.response && error.response.status === 401) {
88-
console.log('registerToken', error.response.data.registerToken);
89-
setRegisterToken(error.response.data.registerToken);
90-
if (storeUrl) {
91-
router.push(`/signup/step1?url=${storeUrl}`);
92-
clearLetterUrl();
93-
} else {
94-
router.push('/signup/step1');
95-
}
96-
}
97-
});
98-
}
99-
} catch (error) {
100-
console.error(error);
101-
clearLetterUrl();
102-
return;
140+
}
141+
});
103142
}
104-
};
105-
getToken();
106-
}, [absoluteUrl]);
143+
} catch (error) {
144+
console.log('oauth token 에러');
145+
console.error(error);
146+
clearLetterUrl();
147+
return;
148+
}
149+
}, [oauthAccessToken]);
107150

108151
return (
109152
<Container>

src/components/signup/SocialGoogle.tsx

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,36 @@ import Loader, { LoaderContainer } from '../common/Loader';
88
const SocialGoogle = () => {
99
const searchParams = useSearchParams();
1010
const url = searchParams.get('url');
11-
const REST_API_KEY = process.env.NEXT_PUBLIC_REST_API_KEY;
12-
const GOOGLE_URL = '/login/google';
1311
const [absoluteUrl, setabsoluteUrl] = useState('');
1412

1513
useEffect(() => {
1614
if (typeof window !== 'undefined') {
1715
setabsoluteUrl(
18-
window.location.protocol + '//' + window.location.host + '/login/kakao'
16+
window.location.protocol +
17+
'//' +
18+
window.location.host +
19+
'/login/auth?type=google'
1920
);
2021
}
2122
}, []);
2223

2324
const handleLogin = () => {
24-
//이때 localStorage에 저장된 accessToken이 만료되었는지 확인해야함.
25-
// if (accessToken) {
26-
// if (url) {
27-
// router.push(`/verify?url=${url}`);
28-
// } else {
29-
// router.push("/");
30-
// }
31-
// setAccessToken(accessToken);
32-
// } else {
33-
//받은 편지를 통해 들어올 경우 url를 저장한다.
3425
if (url) {
3526
setLetterUrl(url);
3627
}
37-
window.location.href = GOOGLE_URL;
28+
const GOOGLE_CLIENT_ID = process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID;
29+
const scope = 'openid profile email';
30+
31+
const authUrl = [
32+
'https://accounts.google.com/o/oauth2/v2/auth',
33+
`?client_id=${GOOGLE_CLIENT_ID}`,
34+
`&redirect_uri=${encodeURIComponent(absoluteUrl)}`,
35+
`&response_type=code`,
36+
`&scope=${encodeURIComponent(scope)}`,
37+
`&access_type=offline`,
38+
`&prompt=consent`
39+
].join('');
40+
window.location.href = authUrl;
3841
};
3942

4043
return (

0 commit comments

Comments
 (0)