Skip to content

Commit 1a7b278

Browse files
committed
feat :: 구글 로그인 인증 로직 구현
1 parent 3bc4855 commit 1a7b278

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ dist-ssr
2222
*.njsproj
2323
*.sln
2424
*.sw?
25+
.env

src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import Login from "./pages/Login";
66
import Reservation from "./pages/Reservation";
77
import ReservationComplete from "./pages/ReservationComplete";
88
import DesignerDetail from "./pages/DesignerDetail";
9+
import OAuthCallback from "./pages/OAuthCallback";
910

1011
function App() {
1112
return (
1213
<Router>
1314
<Routes>
1415
{/* 기본 랜딩 페이지 (/) */}
1516
<Route path="/" element={<Landing />} />
17+
<Route path="/oauth/callback" element={<OAuthCallback />} />
1618
<Route path="/login" element={<Login />} />
1719
<Route path="/reservation" element={<Reservation />} />
1820
<Route path="/reservationcomplete" element={<ReservationComplete />} />

src/pages/Landing.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
import "../styles/Landing.styles.css";
22

33
export default function LandingPage() {
4+
const handleGoogleLogin = async () => {
5+
try {
6+
const res = await fetch(`${import.meta.env.VITE_BACKEND_URL}/api/oauth2/login`);
7+
if (!res.ok) throw new Error("로그인 URL 요청 실패");
8+
9+
const loginUrl = await res.text(); // 응답이 단순 URL일 경우
10+
window.location.href = loginUrl; // 응답받은 URL로 이동
11+
} catch (err) {
12+
console.error("Google Login Error:", err);
13+
}
14+
};
15+
416
return (
517
<div className="landing-container">
618
<header className="header">
@@ -18,7 +30,7 @@ export default function LandingPage() {
1830
</div>
1931

2032
<div className="button-container">
21-
<button className="google-login-btn">
33+
<button className="google-login-btn" onClick={handleGoogleLogin}>
2234
<img src="/icons/google-icon.svg" alt="Google" />
2335
구글로 시작하기
2436
</button>

src/pages/OAuthCallback.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { useEffect } from "react";
2+
import { useNavigate } from "react-router-dom";
3+
4+
export default function OAuthCallback() {
5+
const navigate = useNavigate();
6+
7+
useEffect(() => {
8+
const urlParams = new URLSearchParams(window.location.search);
9+
const code = urlParams.get("code");
10+
11+
if (!code) {
12+
console.error("Authorization code가 없습니다.");
13+
navigate("/"); // 로그인 실패 시 홈으로 리디렉트
14+
return;
15+
}
16+
17+
const formData = new URLSearchParams();
18+
formData.append("code", code);
19+
20+
fetch(`${import.meta.env.VITE_BACKEND_URL}/api/oauth2/callback`, {
21+
method: "POST",
22+
headers: {
23+
"Content-Type": "application/x-www-form-urlencoded",
24+
},
25+
body: formData,
26+
credentials: "include", // 쿠키 포함 (RefreshToken 저장)
27+
})
28+
.then((res) => {
29+
if (!res.ok) throw new Error("서버 응답 오류");
30+
31+
const accessToken = res.headers.get("Authorization"); // 응답 헤더에서 AccessToken 추출
32+
if (accessToken) {
33+
localStorage.setItem("accessToken", accessToken);
34+
navigate("/designerlist"); // 로그인 성공 후 디자이너 리스트 페이지로 이동
35+
} else {
36+
throw new Error("AccessToken이 없습니다.");
37+
}
38+
})
39+
.catch((err) => {
40+
console.error("OAuth Callback Error:", err);
41+
navigate("/"); // 로그인 실패 시 홈으로 이동
42+
});
43+
}, [navigate]);
44+
45+
return <div>로그인 처리 중...</div>;
46+
}

0 commit comments

Comments
 (0)