Skip to content

Commit b032f29

Browse files
yellowjang장아영
andauthored
[#128] ♻️ 로그인, 로그아웃, 회원가입 query로 변경 및 리팩토링 (#129)
* [#128] 🗑️ remove axios from pmpm-lock.yaml * [#128] ♻️ create 'useSignIn' query * [#128] ♻️ create 'useSignUp' query * [#128] ♻️ create 'SignIn', 'SignOut' fetch function * [#128] ♻️ create 'useSignOut' query * [#128] 🔧 install 'ky' * [#128] ✨ create ky api (backendApi, proxyApi) * [#128] ♻️ fetch -> ky * [#128] 🗑️ remove unused import * [#128] 🐛 fix ky error --------- Co-authored-by: 장아영 <[email protected]>
1 parent 0363b57 commit b032f29

File tree

13 files changed

+2261
-6056
lines changed

13 files changed

+2261
-6056
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"dependencies": {
33
"@tanstack/react-query": "^5.59.19",
44
"clsx": "^2.1.1",
5+
"ky": "^1.7.2",
56
"next": "^15.0.2",
67
"react": "^18.3.1",
78
"react-dom": "^18.3.1",

pnpm-lock.yaml

Lines changed: 2078 additions & 5921 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

queries/useSignIn.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use client'
2+
3+
import { useRouter } from 'next/navigation'
4+
5+
import { useMutation } from '@tanstack/react-query'
6+
7+
import { SignIn } from '@/services/auth/auth'
8+
9+
export const useSignInMutation = () => {
10+
const router = useRouter()
11+
12+
return useMutation({
13+
mutationFn: SignIn,
14+
onSuccess: (result) => {
15+
console.log('Login successful', result)
16+
17+
alert('로그인 성공')
18+
router.push(`/`)
19+
},
20+
onError: (error: unknown) => {
21+
console.error('Login Error:', error)
22+
alert('로그인 요청 중 오류가 발생했습니다')
23+
},
24+
})
25+
}

queries/useSignOut.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use client'
2+
3+
import { useRouter } from 'next/navigation'
4+
5+
import { useMutation } from '@tanstack/react-query'
6+
7+
import { SignOut } from '@/services/auth/auth'
8+
9+
export const useSignOutMutation = () => {
10+
const router = useRouter()
11+
12+
return useMutation({
13+
mutationFn: SignOut,
14+
onSuccess: result => {
15+
console.log('로그아웃 성공', result)
16+
17+
alert('로그아웃 성공')
18+
router.push(`/sign-in`)
19+
},
20+
onError: (error: unknown) => {
21+
console.error('Logout Error:', error)
22+
alert('로그아웃 요청 중 오류가 발생했습니다')
23+
},
24+
})
25+
}

queries/useSignUp.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use client'
2+
3+
import { useRouter } from 'next/navigation'
4+
5+
import { useMutation } from '@tanstack/react-query'
6+
7+
import { SignUp } from '@/services/auth/auth'
8+
9+
export const useSignUpMutation = () => {
10+
const router = useRouter()
11+
12+
return useMutation({
13+
mutationFn: SignUp,
14+
onSuccess: (result) => {
15+
console.log('회원가입 성공', result)
16+
alert('회원가입 성공')
17+
router.push(`/sign-in`)
18+
},
19+
onError: (error: unknown) => {
20+
console.error('SignUp Error:', error)
21+
alert('회원가입 요청 중 오류가 발생했습니다')
22+
},
23+
})
24+
}

src/app/(pages)/sign-in/page.tsx

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,23 @@
11
'use client'
22

3-
import { useRouter } from 'next/navigation'
4-
53
import { SubmitHandler, useForm } from 'react-hook-form'
64

75
import { SignInRequest } from '@/types/auth.types'
6+
import { useSignInMutation } from 'queries/useSignIn'
7+
88

99
export default function LoginPage(): JSX.Element {
10-
const router = useRouter()
10+
1111
const {
1212
register,
1313
handleSubmit,
1414
formState: { errors },
1515
} = useForm<SignInRequest>()
1616

17-
const onSubmit: SubmitHandler<SignInRequest> = async data => {
18-
try {
19-
const response = await fetch(`/api/auth/sign-in`, {
20-
method: 'POST',
21-
headers: { 'Content-Type': 'application/json' },
22-
body: JSON.stringify(data),
23-
})
24-
25-
if (!response.ok) {
26-
console.error('Login failed')
27-
alert('로그인 실패 프록시 전달')
28-
return
29-
}
17+
const mutation = useSignInMutation()
3018

31-
const result = await response.json()
32-
console.log('Login successful:', result)
33-
alert('로그인 성공')
34-
router.push('/')
35-
} catch (error) {
36-
console.error('Login error', error)
37-
alert('로그인 요청 중 오류 발생')
38-
}
19+
const onSubmit: SubmitHandler<SignInRequest> = data => {
20+
mutation.mutate(data)
3921
}
4022

4123
return (

src/app/(pages)/sign-up/page.tsx

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import { useRouter } from 'next/navigation'
55
import { SubmitHandler, useForm } from 'react-hook-form'
66

77
import { SignUpRequest } from '@/types/auth.types'
8-
9-
import { SignUp } from '@/services/auth/auth'
8+
import { useSignUpMutation } from 'queries/useSignUp'
109

1110
export default function SignUpPage(): JSX.Element {
1211
const router = useRouter()
@@ -15,24 +14,10 @@ export default function SignUpPage(): JSX.Element {
1514
handleSubmit,
1615
formState: { errors },
1716
} = useForm<SignUpRequest>()
17+
const mutation = useSignUpMutation()
1818

19-
const onSubmit: SubmitHandler<SignUpRequest> = async data => {
20-
try {
21-
const response = await SignUp(data)
22-
if (!response.ok) {
23-
console.error('회원가입 실패')
24-
alert('회원가입 실패')
25-
return
26-
}
27-
const result = await response.json()
28-
console.log('회원가입 성공:', result)
29-
30-
alert('회원가입이 완료되었습니다!')
31-
router.push('/sign-in')
32-
} catch (error) {
33-
console.error('회원가입 요청 중 오류 발생', error)
34-
alert('회원가입 중 오류 발생')
35-
}
19+
const onSubmit: SubmitHandler<SignUpRequest> = data => {
20+
mutation.mutate(data)
3621
}
3722

3823
return (

src/app/api/auth/refresh/route.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,31 @@
11
import { NextResponse } from 'next/server'
22

3+
import { backendApi } from '@/services/api'
4+
35
const BACKEND_BASE_URL = process.env.NEXT_PUBLIC_BACKEND_BASE_URL
46

57
export const POST = async (req: Request): Promise<NextResponse> => {
68
const { refreshToken } = await req.json()
79

810
try {
9-
const response = await fetch(`${BACKEND_BASE_URL}/refresh`, {
10-
method: 'POST',
11-
headers: { 'Content-Type': 'application/json' },
12-
body: JSON.stringify({ refreshToken }),
13-
})
11+
const { accessToken } = await backendApi
12+
.post('refresh', { json: { refreshToken } })
13+
.json<{ accessToken: string }>()
14+
return NextResponse.json({ success: true, accessToken })
15+
} catch (error: any) {
16+
console.error('토큰 갱신 에러:', error)
1417

15-
if (!response.ok) {
16-
const errorData = await response.json()
18+
if (error.response) {
19+
const errorData = await error.response.json()
1720
return NextResponse.json(
1821
{
1922
success: false,
20-
message: errorData.message || 'Token refresh failed',
23+
message: errorData.messassage || '토큰 갱신 실패',
2124
},
22-
{ status: response.status }
25+
{ status: error.response.status }
2326
)
2427
}
2528

26-
const { accessToken } = await response.json()
27-
28-
return NextResponse.json({ success: true, accessToken })
29-
} catch (error: any) {
30-
console.error('Token refresh error:', error)
3129
return NextResponse.json(
3230
{ success: false, message: 'Internal server error' },
3331
{ status: 500 }

src/app/api/auth/sign-in/route.ts

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,52 @@
11
import { NextResponse } from 'next/server'
22

3-
const BACKEND_BASE_URL = process.env.NEXT_PUBLIC_BACKEND_BASE_URL
3+
import { SignInRequest, SignInResponseResult } from '@/types/auth.types'
4+
5+
import { backendApi } from '@/services/api'
46

57
export const POST = async (req: Request): Promise<NextResponse> => {
68
const { email, password } = await req.json()
7-
const response = await fetch(`${BACKEND_BASE_URL}/v1/auth/sign-in`, {
8-
headers: { 'Content-Type': 'application/json' },
9-
method: 'POST',
10-
body: JSON.stringify({ email, password }),
11-
})
129

13-
if (!response.ok) {
10+
try {
11+
const { accessToken, refreshToken } = await backendApi
12+
.post('v1/auth/sign-in', {
13+
json: { email, password },
14+
})
15+
.json<SignInResponseResult>()
16+
17+
const res = NextResponse.json({ success: true })
18+
19+
res.cookies.set('accessToken', accessToken, {
20+
httpOnly: true,
21+
secure: true,
22+
sameSite: 'strict',
23+
path: '/',
24+
maxAge: 3600,
25+
})
26+
27+
res.cookies.set('refreshToken', refreshToken, {
28+
httpOnly: true,
29+
secure: true,
30+
sameSite: 'strict',
31+
path: '/',
32+
maxAge: 1209600,
33+
})
34+
35+
return res
36+
} catch (error: any) {
37+
console.error('Login failed:', error)
38+
39+
if (error.response) {
40+
const errorData = await error.response.json()
41+
return NextResponse.json(
42+
{ error: errorData.message || 'Login failed' },
43+
{ status: error.response.status }
44+
)
45+
}
46+
1447
return NextResponse.json(
15-
{ error: 'Login failed' },
16-
{ status: response.status }
48+
{ error: 'Internal server error' },
49+
{ status: 500 }
1750
)
1851
}
19-
20-
const data = await response.json()
21-
const { accessToken, refreshToken } = data.result
22-
23-
const res = NextResponse.json({ success: true })
24-
25-
res.cookies.set('accessToken', accessToken, {
26-
httpOnly: true,
27-
secure: true,
28-
sameSite: 'strict',
29-
path: '/',
30-
maxAge: 3600,
31-
})
32-
33-
res.cookies.set('refreshToken', refreshToken, {
34-
httpOnly: true,
35-
secure: true,
36-
sameSite: 'strict',
37-
path: '/',
38-
maxAge: 1209600,
39-
})
40-
41-
return res
4252
}

src/app/page.tsx

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,12 @@
11
'use client'
22

3-
import { useRouter } from 'next/navigation'
3+
import { useSignOutMutation } from 'queries/useSignOut'
44

55
export default function Home(): JSX.Element {
6-
const router = useRouter()
6+
const mutation = useSignOutMutation()
77

88
const handleLogout = async () => {
9-
try {
10-
const response = await fetch(`/api/auth/sign-out`, {
11-
method: 'POST',
12-
headers: { 'Content-Type': 'application/json' },
13-
})
14-
if (!response.ok) {
15-
console.error('Logout failed')
16-
alert('로그아웃 실패 프록시')
17-
return
18-
}
19-
console.log('Logout successful')
20-
alert('로그아웃 성공 프록시')
21-
router.push('/sign-in')
22-
} catch (error) {
23-
console.error('Logout error', error)
24-
alert('로그아웃 요청 중 오류 발생')
25-
}
9+
mutation.mutate()
2610
}
2711

2812
return (

0 commit comments

Comments
 (0)