WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit ac3ca47

Browse files
authored
Merge pull request #257 from JECT-Study/fix-authentication
Fix authentication
2 parents b19a1b1 + 9f3e643 commit ac3ca47

File tree

24 files changed

+246
-379
lines changed

24 files changed

+246
-379
lines changed

service/app/public/avatar.svg

Lines changed: 0 additions & 9 deletions
This file was deleted.

service/app/src/app/__tests__/helpers/auth.setup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ setup("authenticate", async ({ page }) => {
1414
await page.goto("/")
1515

1616
await page.waitForURL("/")
17-
await expect(page.getByRole("button", { name: "내 게임" })).toBeVisible()
17+
await expect(page.getByRole("link", { name: "내 게임" })).toBeVisible()
1818

1919
await page.context().storageState({ path: authFile })
2020
})

service/app/src/app/__tests__/home.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ test.describe("홈 화면: 비로그인 상태", () => {
2222
page,
2323
}) => {
2424
await pageObj.clickKakaoLoginButton()
25-
await page.waitForURL("/login")
25+
await page.waitForURL(/\/login(\?|$)/, { waitUntil: "commit" })
2626
})
2727
})
2828

service/app/src/app/__tests__/homePOM.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ export class HomePOM {
3939
// 네비게이션 영역 (비로그인 상태)
4040
this.homeLogoImage = page.getByAltText("홈 로고")
4141
this.themeToggleButton = page.getByTestId("theme-toggle-button")
42-
this.kakaoLoginButton = page.getByRole("button", {
42+
this.kakaoLoginButton = page.getByRole("link", {
4343
name: "간편로그인해서 게임 만들기",
4444
})
4545

4646
// 네비게이션 영역 (로그인 상태)
47-
this.myGamesButton = page.getByRole("button", { name: "내 게임" })
48-
this.createGameButton = page.getByRole("button", {
47+
this.myGamesButton = page.getByRole("link", { name: "내 게임" })
48+
this.createGameButton = page.getByRole("link", {
4949
name: "게임 만들기",
5050
exact: true,
5151
})

service/app/src/app/game/[gameId]/setup/__tests__/team-management.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,15 @@ test.describe("게임 설정 - 팀 관리 E2E 테스트", () => {
118118
}) => {
119119
const entry = "/games"
120120
await page.evaluate((e) => {
121-
window.sessionStorage.setItem("entry", e)
121+
window.sessionStorage.setItem("entry:game", e)
122122
}, entry)
123123
await gameSetupPage.clickHomeLogo()
124124
await expect(page).toHaveURL(entry)
125125
})
126126

127127
test("entry 정보가 없으면 홈 페이지로 이동해야 한다", async ({ page }) => {
128128
await page.evaluate(() => {
129-
window.sessionStorage.removeItem("entry")
129+
window.sessionStorage.removeItem("entry:game")
130130
})
131131
await gameSetupPage.clickHomeLogo()
132132
await expect(page).toHaveURL("/")
@@ -137,7 +137,7 @@ test.describe("게임 설정 - 팀 관리 E2E 테스트", () => {
137137
}) => {
138138
const entry = "/games"
139139
await page.evaluate((e) => {
140-
window.sessionStorage.setItem("entry", e)
140+
window.sessionStorage.setItem("entry:game", e)
141141
}, entry)
142142
await gameSetupPage.clickExitIcon()
143143
await expect(page).toHaveURL(entry)

service/app/src/app/login/kakao/page.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
"use client"
22

33
import { useRouter, useSearchParams } from "next/navigation"
4-
import { Suspense, useEffect } from "react"
4+
import { Suspense, useEffect, useRef } from "react"
55

66
import { useAuthStore } from "@/entities/auth"
7+
import { clearEntry, ENTRY_KEYS, getEntry } from "@/shared/lib/saveEntry"
78

89
function KakaoCallbackContent() {
910
const router = useRouter()
1011
const searchParams = useSearchParams()
1112
const { login } = useAuthStore()
13+
const handledRef = useRef(false)
1214

1315
useEffect(() => {
16+
if (handledRef.current) return
17+
handledRef.current = true
18+
1419
const handleCallback = async () => {
1520
const code = searchParams.get("code")
1621
const error = searchParams.get("error")
@@ -19,7 +24,9 @@ function KakaoCallbackContent() {
1924
throw new Error(error || "인증 코드를 받지 못했습니다.")
2025

2126
await login(code)
22-
router.push("/")
27+
const returnTo = getEntry(ENTRY_KEYS.auth) ?? "/"
28+
clearEntry(ENTRY_KEYS.auth)
29+
router.replace(returnTo)
2330
}
2431

2532
handleCallback()
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"use client"
2+
3+
import { useRouter } from "next/navigation"
4+
import { useEffect } from "react"
5+
6+
import { MSW_MOCK_CODE } from "@/mocks/handlers/auth"
7+
import { ENTRY_KEYS, saveEntry } from "@/shared/lib/saveEntry"
8+
9+
export function KakaoLoginClient({ returnTo }: { returnTo?: string }) {
10+
const router = useRouter()
11+
12+
const kakaoClientId = process.env.NEXT_PUBLIC_KAKAO_CLIENT_ID
13+
const redirectUri = process.env.NEXT_PUBLIC_KAKAO_REDIRECT_URI
14+
15+
useEffect(() => {
16+
if (returnTo) saveEntry(ENTRY_KEYS.auth, returnTo)
17+
18+
if (process.env.NODE_ENV === "development") {
19+
router.replace(`/login/kakao/?code=${MSW_MOCK_CODE}`)
20+
return
21+
}
22+
23+
if (!kakaoClientId || !redirectUri) return
24+
25+
const kakaoAuthUrl = `https://kauth.kakao.com/oauth/authorize?client_id=${kakaoClientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code`
26+
27+
router.replace(kakaoAuthUrl)
28+
}, [router, kakaoClientId, redirectUri, returnTo])
29+
30+
return (
31+
<div className="flex min-h-screen items-center justify-center bg-background-primary">
32+
<div className="flex flex-col items-center gap-16">
33+
<div className="size-32 animate-spin rounded-full border-4 border-blue-400 border-t-transparent"></div>
34+
<p className="text-sm text-text-primary">
35+
카카오 로그인으로 이동 중...
36+
</p>
37+
</div>
38+
</div>
39+
)
40+
}

service/app/src/app/login/page.tsx

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,24 @@
1-
"use client"
1+
import { Suspense } from "react"
22

3-
import { useRouter } from "next/navigation"
4-
import { useEffect } from "react"
5-
6-
import { MSW_MOCK_CODE } from "@/mocks/handlers/auth"
7-
8-
export default function KakaoLoginPage() {
9-
const router = useRouter()
10-
11-
const kakaoClientId = process.env.NEXT_PUBLIC_KAKAO_CLIENT_ID
12-
const redirectUri = process.env.NEXT_PUBLIC_KAKAO_REDIRECT_URI
13-
14-
useEffect(() => {
15-
if (process.env.NODE_ENV === "development") {
16-
router.replace(`/login/kakao/?code=${MSW_MOCK_CODE}`)
17-
return
18-
}
19-
20-
if (!kakaoClientId || !redirectUri) return
21-
22-
const kakaoAuthUrl = `https://kauth.kakao.com/oauth/authorize?client_id=${kakaoClientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code`
23-
24-
router.replace(kakaoAuthUrl)
25-
}, [router, kakaoClientId, redirectUri])
3+
import { KakaoLoginClient } from "./kakaoLoginClient"
264

5+
export default function KakaoLoginPage({
6+
searchParams,
7+
}: {
8+
searchParams: { returnTo?: string }
9+
}) {
2710
return (
28-
<div className="flex min-h-screen items-center justify-center bg-background-primary">
29-
<div className="flex flex-col items-center gap-16">
30-
<div className="size-32 animate-spin rounded-full border-4 border-blue-400 border-t-transparent"></div>
31-
<p className="text-sm text-text-primary">
32-
카카오 로그인으로 이동 중...
33-
</p>
34-
</div>
35-
</div>
11+
<Suspense
12+
fallback={
13+
<div className="flex min-h-screen items-center justify-center">
14+
<div className="text-center">
15+
<div className="mb-4">페이지를 준비하고 있습니다</div>
16+
<div className="mx-auto size-8 animate-spin rounded-full border-b-2 border-gray-900"></div>
17+
</div>
18+
</div>
19+
}
20+
>
21+
<KakaoLoginClient returnTo={searchParams.returnTo} />
22+
</Suspense>
3623
)
3724
}

service/app/src/app/providers.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ThemeProvider } from "next-themes"
55
import { NuqsAdapter } from "nuqs/adapters/next/app"
66
import { OverlayProvider } from "overlay-kit"
77

8+
import { AuthProvider } from "@/entities/auth/ui/authProvider"
89
import { MSWProvider } from "@/mocks/mswProvider"
910
import { queryClient } from "@/shared/lib/queryClient"
1011

@@ -23,7 +24,9 @@ export function Providers({ children }: ProvidersProps) {
2324
>
2425
<OverlayProvider>
2526
<MSWProvider>
26-
<NuqsAdapter>{children}</NuqsAdapter>
27+
<AuthProvider>
28+
<NuqsAdapter>{children}</NuqsAdapter>
29+
</AuthProvider>
2730
</MSWProvider>
2831
</OverlayProvider>
2932
</ThemeProvider>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { fetchClient } from "@/shared/api/fetchClient"
2+
3+
export const validateSession = async () => {
4+
const response = await fetchClient.get<null>("users/me/games?limit=1") // TODO: 엔드포인트 생성 후 변경
5+
return response.json()
6+
}

0 commit comments

Comments
 (0)