-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #67 from dnd-side-project/feature/66-kakao-login-api
Feature : kakao login api 구현
- Loading branch information
Showing
11 changed files
with
188 additions
and
8 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import axios, { AxiosError, InternalAxiosRequestConfig } from 'axios'; | ||
|
||
import { BASE_API_URL } from '@/constants'; | ||
import { getCookie } from '@/utils/cookieController'; | ||
|
||
import type { CustomInstance } from './type'; | ||
|
||
const privateApi: CustomInstance = axios.create({ | ||
baseURL: `${BASE_API_URL}/api`, | ||
withCredentials: true, | ||
}); | ||
|
||
privateApi.interceptors.request.use( | ||
async (config: InternalAxiosRequestConfig) => { | ||
try { | ||
const accessToken = getCookie('accessToken'); | ||
config.headers.Authorization = `Bearer ${accessToken}`; | ||
return config; | ||
} catch (error) { | ||
return Promise.reject(error); | ||
} | ||
}, | ||
(error: AxiosError) => { | ||
Promise.reject(error); | ||
} | ||
); | ||
|
||
privateApi.interceptors.response.use((response) => response.data); | ||
|
||
export default privateApi; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
src/app/(Sub)/api/users/login/oauth/kakao/components/LoginSection.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
'use client'; | ||
|
||
import { useRouter } from 'next/navigation'; | ||
|
||
import { useRegisterQuery } from '@/apis'; | ||
import { Loading } from '@/components/Loading'; | ||
import { setCookie } from '@/utils/cookieController'; | ||
|
||
interface LoginSectionProps { | ||
code: string; | ||
} | ||
export default function LoginSection({ code }: LoginSectionProps) { | ||
const router = useRouter(); | ||
const { data } = useRegisterQuery(code); | ||
console.log(data); | ||
const { token, email, nickname } = data; | ||
const { accessToken, refreshToken, expiresIn } = token; | ||
setCookie('accessToken', accessToken); | ||
setCookie('refreshToken', refreshToken); | ||
router.replace('/menu'); | ||
|
||
return <Loading />; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { QueryAsyncBoundary } from '@suspensive/react-query'; | ||
|
||
import LoginSection from './components/LoginSection'; | ||
import { getRegister } from '@/apis'; | ||
import { RejectedFallback } from '@/components/ErrorBoundary'; | ||
import { Loading } from '@/components/Loading'; | ||
import { HydrationProvider } from '@/components/Provider/HydrationProvider'; | ||
|
||
interface PageProps { | ||
searchParams: { | ||
code: string; | ||
}; | ||
} | ||
|
||
export default function Page({ searchParams }: PageProps) { | ||
const { code } = searchParams; | ||
|
||
return ( | ||
<QueryAsyncBoundary rejectedFallback={RejectedFallback} pendingFallback={<Loading />}> | ||
<HydrationProvider queryKey={['register']} queryFn={() => getRegister(code)}> | ||
<LoginSection code={code} /> | ||
</HydrationProvider> | ||
</QueryAsyncBoundary> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import Image from 'next/image'; | ||
|
||
import { Modal } from '@/components/Modal'; | ||
import { Spacing } from '@/components/Spacing'; | ||
|
||
interface LoginModalProps { | ||
onClose: () => void; | ||
} | ||
export default function LoginModal({ onClose }: LoginModalProps) { | ||
const link = `https://kauth.kakao.com/oauth/authorize?client_id=${process.env.NEXT_PUBLIC_KAKAO_SERVER_KEY}&redirect_uri=${process.env.NEXT_PUBLIC_SITE_URL}/api/users/login/oauth/kakao&response_type=code`; | ||
|
||
const handleLogin = () => { | ||
window.location.href = link; | ||
}; | ||
|
||
return ( | ||
<Modal onCloseOutside={onClose}> | ||
<Spacing size={32} /> | ||
<h4>간편 로그인</h4> | ||
<Spacing size={8} /> | ||
<p> | ||
로그인해야 북마크를 쓸 수 있어요. | ||
<br /> | ||
카카오로 3초만에 가입할 수 있어요! | ||
</p> | ||
<Spacing size={16} /> | ||
<Image | ||
src="/images/kakao-login.png" | ||
width={268} | ||
height={54} | ||
alt="kakao-login" | ||
className="cursor-pointer" | ||
onClick={handleLogin} | ||
/> | ||
<Spacing size={32} /> | ||
</Modal> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
const isServer = typeof window === 'undefined'; | ||
|
||
export const setCookie = async (key: string, value: string, options?: { expires?: Date }) => { | ||
// 서버 측 쿠키 | ||
if (isServer) { | ||
const { cookies } = await import('next/headers'); | ||
cookies().set(key, value, { | ||
expires: options?.expires, | ||
}); | ||
return; | ||
} | ||
|
||
// 클라이언트 측 쿠키 | ||
document.cookie = `${key}=${value}; path=/; ${ | ||
options?.expires ? `expires=${options.expires.toUTCString()}` : '' | ||
}`; | ||
}; | ||
|
||
export const getCookie = async (key: string) => { | ||
// 서버측 쿠키 | ||
if (isServer) { | ||
const { cookies } = await import('next/headers'); | ||
return cookies().get(key); | ||
} | ||
|
||
// 클라이언트 측 쿠키 | ||
const value = `; ${document.cookie}`; | ||
const parts = value.split(`; ${key}=`); | ||
|
||
return parts.pop()?.split(';').shift(); | ||
}; | ||
|
||
export const removeCookie = async (key: string) => { | ||
// 서버측 쿠키 | ||
if (isServer) { | ||
const { cookies } = await import('next/headers'); | ||
cookies().set(key, ''); | ||
return; | ||
} | ||
|
||
// 클라이언트 측 쿠키 | ||
document.cookie = `${key}=; expires=Thu, 01 Jan 1999 00:00:10 GMT;`; | ||
}; |