From 53113f6bad2b6c710276bca3179b36ff21527868 Mon Sep 17 00:00:00 2001 From: afds4567 <33995840+afds4567@users.noreply.github.com> Date: Tue, 19 Sep 2023 17:06:54 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EC=96=B4=EC=A7=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20url=20?= =?UTF-8?q?=EC=9D=B8=ED=92=8B=20=EC=BB=A8=ED=85=8C=EC=9D=B4=EB=84=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/NewTopic.tsx | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/frontend/src/pages/NewTopic.tsx b/frontend/src/pages/NewTopic.tsx index a778b8f8..28c1f06e 100644 --- a/frontend/src/pages/NewTopic.tsx +++ b/frontend/src/pages/NewTopic.tsx @@ -157,22 +157,6 @@ const NewTopic = () => { - - - - Date: Tue, 19 Sep 2023 17:13:38 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20refreshToken=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/apis/getApi.ts | 87 +++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 17 deletions(-) diff --git a/frontend/src/apis/getApi.ts b/frontend/src/apis/getApi.ts index f7b59bb2..8980e143 100644 --- a/frontend/src/apis/getApi.ts +++ b/frontend/src/apis/getApi.ts @@ -1,31 +1,84 @@ +const decodeToken = (token: string) => { + const tokenParts = token.split('.'); + if (tokenParts.length !== 3) { + throw new Error('토큰이 잘못되었습니다.'); + } + + const decodedPayloadString = atob(tokenParts[1]); + console.log('decodedPayloadString', decodedPayloadString); + return JSON.parse(decodedPayloadString); +}; + +async function refreshToken(headers: Headers): Promise { + const refreshResponse = await fetch(`${DEFAULT_PROD_URL}/refresh-token`, { + method: 'POST', + headers, + }); + + if (!refreshResponse.ok) { + throw new Error('Failed to refresh access token.'); + } + console.log('refreshResponse', refreshResponse); + return await refreshResponse.text(); +} + +async function withTokenRefresh(callback: () => Promise): Promise { + let userToken = localStorage.getItem('userToken'); + console.log('userToken', userToken); + if (userToken) { + const decodedPayloadObject = decodeToken(userToken); + console.log('decodedPayloadObject', decodedPayloadObject); + // decodeToken의 결과로 만료 여부 판단 + if (decodedPayloadObject.exp * 1000 < Date.now()) { + console.log('AccessToken 만료되어 재요청합니다'); + + const headers: any = { Authorization: `Bearer ${userToken}` }; + //새로운 토큰 재발급 + userToken = await refreshToken(headers); + localStorage.setItem('userToken', userToken); + console.log('localStorage에 새로운 토큰 적용 성공!'); + } + } + + //인자로 넘겨준 실제 fetch함수 실행 + console.log('callback 실행'); + return callback(); +} + import { DEFAULT_PROD_URL } from '../constants'; +const API_URL = + process.env.NODE_ENV === 'development' + ? 'http://localhost:3000' + : DEFAULT_PROD_URL; + interface Headers { 'content-type': string; [key: string]: string; } export const getApi = async (url: string) => { - const apiUrl = `${DEFAULT_PROD_URL + url}`; - const userToken = localStorage.getItem('userToken'); - const headers: Headers = { - 'content-type': 'application/json', - }; + await withTokenRefresh(async () => { + const apiUrl = `${DEFAULT_PROD_URL + url}`; + const userToken = localStorage.getItem('userToken'); + const headers: any = {}; - if (userToken) { - headers['Authorization'] = `Bearer ${userToken}`; - } + if (userToken) { + headers['Authorization'] = `Bearer ${userToken}`; + } - const response = await fetch(apiUrl, { - method: 'GET', - headers, - }); + console.log('response', DEFAULT_PROD_URL + url); - if (response.status >= 400) { - throw new Error('[SERVER] GET 요청에 실패했습니다.'); - } + const response = await fetch(apiUrl, { method: 'GET', headers }); - const responseData: T = await response.json(); + console.log(response); - return responseData; + if (response.status >= 400) { + throw new Error('[SERVER] GET 요청에 실패했습니다.'); + } + + const responseData: T = await response.json(); + + return responseData; + }); };