From 6e4055ea1b67815029bb9ef1939c46a3bb81bdb1 Mon Sep 17 00:00:00 2001 From: Raymond Date: Thu, 15 Feb 2024 15:49:05 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=9D=B8=EC=A6=9D=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=98=A4=EB=A5=98=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 디버깅용 인터셉터 로그 적용 - handler응답 타입 변경 - auth/provider 에러 핸들링 방식변경 - Cookie lax 적용 --- lib/namui-api.ts | 30 ++++++++++++++++++--------- pages/_app.tsx | 6 +++--- pages/api/auth/[provider].ts | 38 ++++++++++++----------------------- provider/session-provider.tsx | 6 +++--- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/lib/namui-api.ts b/lib/namui-api.ts index 6eb6713..cdbedc6 100644 --- a/lib/namui-api.ts +++ b/lib/namui-api.ts @@ -14,7 +14,7 @@ export class NamuiApi { private static instanceOption: CreateAxiosDefaults = { baseURL: process.env.NEXT_PUBLIC_API_URL, } - private static accessToken: string + private static accessToken: string = '' /** * @param provider * @returns @@ -24,7 +24,7 @@ export class NamuiApi { method: 'POST', url: `/api/v1/auth/login`, data: { - provider, + provider: provider.toUpperCase(), code, }, }) @@ -40,20 +40,27 @@ export class NamuiApi { private static async getNewToken() { const serverURL = new URL(process.env.NEXT_PUBLIC_API_URL) serverURL.pathname = '/api/v1/refresh' - const response = await fetch(serverURL).then( - (res) => - res.json() as Promise<{ + const response = await fetch(serverURL).then((res) => { + if (res.status > 400) { + throw raiseNamuiErrorFromStatus(res.status) + } else { + return res.json() as Promise<{ data: { accessToken: 'string' } - }>, - ) + }> + } + }) NamuiApi.setToken(response.data.accessToken) return response.data.accessToken } private static injectInterceptor(instance: AxiosInstance) { const onRequest = (config: AxiosRequestConfig): AxiosRequestConfig => { + if (process.env.NODE_ENV === 'development') { + console.log(`[LOG-Request] : ${config.url}`) + console.log(`[LOG-Request] : ${config.headers}`) + } const accessToken = NamuiApi.accessToken config.headers = { @@ -72,7 +79,11 @@ export class NamuiApi { const onResponse = (config: AxiosResponse) => config.data // eslint-disable-next-line @typescript-eslint/no-explicit-any const onErrorResponse = async (error: any) => { - console.log(error) + if (process.env.NODE_ENV === 'development') { + console.log( + `[LOG-RESPONSE-ERROR] : PATH-${error.request.path} ${error?.message}`, + ) + } if (error.response?.status === 401) { const newAccessToken = await this.getNewToken() error.config.headers = { @@ -84,6 +95,7 @@ export class NamuiApi { const errorInstance = axios.isAxiosError(error) ? raiseNamuiErrorFromStatus(error.status || error.response?.status) : error + return Promise.reject(errorInstance) } @@ -112,6 +124,6 @@ export class NamuiApi { private static async handler(config: AxiosRequestConfig) { const instance = this.getInstance() - return instance(config) + return instance(config) as Response } } diff --git a/pages/_app.tsx b/pages/_app.tsx index b35f9cf..cf64f53 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -35,8 +35,8 @@ export default function NamuiWikiApp({ return getLayout( { - NamuiApi.setToken(session?.token?.accessToken) + onSessionChange={(newSession) => { + NamuiApi.setToken(newSession?.token?.accessToken) }} > @@ -63,7 +63,7 @@ NamuiWikiApp.getInitialProps = async ( method: 'GET', headers: headers, }) - const user = await res.json() + const user = (await res.json()) ?? {} return { ...ctx, session: { diff --git a/pages/api/auth/[provider].ts b/pages/api/auth/[provider].ts index 7b402b2..8995505 100644 --- a/pages/api/auth/[provider].ts +++ b/pages/api/auth/[provider].ts @@ -1,8 +1,7 @@ import { AUTH } from '@/constants' -import { BadRequestError, isNamuiError } from '@/error' -import { Oauth, Provider } from '@/lib/auth' +import { BadRequestError, InternalServerError, isNamuiError } from '@/error' +import { Provider } from '@/lib/auth' import { NamuiApi } from '@/lib/namui-api' -import { withError } from '@/lib/server/utils' import withHandler from '@/lib/server/with-handler' import { serialize } from 'cookie' import type { NextApiRequest, NextApiResponse } from 'next' @@ -11,47 +10,36 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { try { const { provider, code } = req.query const parsedProvider = Provider.safeParse(provider) - if (!parsedProvider.success) { - return withError(res, { - status: 400, - message: BadRequestError.message, - }) + if (!parsedProvider.success || !code) { + throw new BadRequestError() } - const url = Oauth.getAuthorizationURL(parsedProvider.data) - if (!url || !code) { - return withError(res, { - status: 400, - message: BadRequestError.message, - }) - } - - const { - data: { accessToken, refreshToken }, - } = await NamuiApi.signIn(parsedProvider.data, code) + const { accessToken, refreshToken } = await NamuiApi.signIn( + parsedProvider.data, + code, + ) res.setHeader('Set-Cookie', [ serialize('accessToken', accessToken, { path: '/', httpOnly: true, secure: true, - sameSite: 'none', + sameSite: 'lax', maxAge: AUTH.ACCESS_EXPIRED_TIME, }), serialize('refreshToken', refreshToken, { path: '/', httpOnly: true, secure: true, - sameSite: 'none', + sameSite: 'lax', maxAge: AUTH.REFRESH_EXPIRED_TIME, }), ]) + res.status(200).redirect('/') } catch (err) { - if (isNamuiError(err)) { - return res.redirect(307, `/?err=${err.name}`).json({ ok: true }) - } + const error = isNamuiError(err) ? err : new InternalServerError() + return res.redirect(307, `/?err=${error.name}`).json({}) } - res.status(200).redirect('/') } export default withHandler({ diff --git a/provider/session-provider.tsx b/provider/session-provider.tsx index c0d6030..e58051b 100644 --- a/provider/session-provider.tsx +++ b/provider/session-provider.tsx @@ -31,7 +31,7 @@ export type SessionContextValue = R extends true } type SessionHandler = { - signin: (args: { provider: ProviderType; callbackUrl?: string }) => void + signin: (args?: { provider: ProviderType; callbackUrl?: string }) => void signout: () => Promise } interface SessionProviderProps extends SessionContextType { @@ -65,7 +65,7 @@ export const SessionProvider = ({ try { if (session?.token?.accessToken) { const newSession = await NamuiApi.getUserData() - setSession((prev) => ({ ...prev, user: newSession.data })) + setSession((prev) => ({ ...prev, user: newSession })) } } catch (error) { setSession(null) @@ -132,7 +132,7 @@ export const useSession = (options?: { const { required } = options ?? {} const signin: SessionHandler['signin'] = useCallback((args) => { - const { provider, callbackUrl } = args + const { provider = 'kakao', callbackUrl } = args ?? {} if (callbackUrl) { sessionStorage.setItem('callbackUrl', callbackUrl) }