Skip to content

Commit

Permalink
Merge branch 'develop-FE' into fix/#472-permission
Browse files Browse the repository at this point in the history
  • Loading branch information
semnil5202 authored Sep 21, 2023
2 parents 3107246 + 94ab841 commit be5ad68
Show file tree
Hide file tree
Showing 11 changed files with 343 additions and 387 deletions.
1 change: 1 addition & 0 deletions frontend/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = {
targets: {
browsers: ['last 2 versions', 'not dead', 'not ie <= 11'],
},
modules: false,
},
],
['@babel/preset-react'],
Expand Down
52 changes: 24 additions & 28 deletions frontend/src/apis/deleteApi.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,35 @@
// const API_URL =
// process.env.NODE_ENV === 'production'
// ? process.env.REACT_APP_API_DEFAULT_PROD
// : process.env.REACT_APP_API_DEFAULT_DEV;

const API_URL = process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : DEFAULT_PROD_URL

import { DEFAULT_PROD_URL } from '../constants';
import { ContentTypeType } from '../types/Api';
import withTokenRefresh from './utils';

interface Headers {
'content-type': string;
[key: string]: string;
}

export const deleteApi = async (url: string, contentType?: ContentTypeType) => {
const apiUrl = `${DEFAULT_PROD_URL + url}`;
const userToken = localStorage.getItem('userToken');
const headers: Headers = {
'content-type': 'application/json',
};

if (userToken) {
headers['Authorization'] = `Bearer ${userToken}`;
}

if (contentType) {
headers['content-type'] = contentType;
}

const response = await fetch(apiUrl, {
method: 'DELETE',
headers,
return await withTokenRefresh(async () => {
const apiUrl = `${DEFAULT_PROD_URL + url}`;
const userToken = localStorage.getItem('userToken');
const headers: Headers = {
'content-type': 'application/json',
};

if (userToken) {
headers['Authorization'] = `Bearer ${userToken}`;
}

if (contentType) {
headers['content-type'] = contentType;
}

const response = await fetch(apiUrl, {
method: 'DELETE',
headers,
});

if (response.status >= 400) {
throw new Error('[SERVER] DELETE ์š”์ฒญ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}
});

if (response.status >= 400) {
throw new Error('[SERVER] DELETE ์š”์ฒญ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}
};
100 changes: 1 addition & 99 deletions frontend/src/apis/getApi.ts
Original file line number Diff line number Diff line change
@@ -1,98 +1,5 @@
let refreshResponse: Promise<Response> | null = null;

const decodeToken = (token: string) => {
const tokenParts = token.split('.');
if (tokenParts.length !== 3) {
throw new Error('ํ† ํฐ์ด ์ž˜๋ชป๋˜์—ˆ์Šต๋‹ˆ๋‹ค.');
}

const decodedPayloadString = atob(tokenParts[1]);

return JSON.parse(decodedPayloadString);
};

async function refreshToken(headers: Headers): Promise<Response> {
if (refreshResponse !== null) {
console.log('if ๋ธ”๋ก ๋‚ด๋ถ€์—์„œ refreshResponse : ', refreshResponse);
return refreshResponse;
}

console.log('refreshResponse:', refreshResponse);

const accessToken = localStorage.getItem('userToken');
try {
// ์„œ๋ฒ„์— ์ƒˆ๋กœ์šด ์—‘์„ธ์Šค ํ† ํฐ์„ ์š”์ฒญํ•˜๊ธฐ ์œ„ํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
refreshResponse = fetch(`${DEFAULT_PROD_URL}/refresh-token`, {
method: 'POST',
headers,
body: JSON.stringify({
accessToken: accessToken,
}),
});

const responseData = await refreshResponse;
refreshResponse = null;

// ์„œ๋ฒ„ ์‘๋‹ต์ด ์„ฑ๊ณต์ ์ธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
if (!responseData.ok) {
console.log('refreshResponse.okํ•˜์ง€ ๋ชปํ•จ');
throw new Error('Failed to refresh access token.');
}

// ์ƒˆ๋กœ์šด ์—‘์„ธ์Šค ํ† ํฐ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
return responseData;
} catch (error) {
// ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์‹คํŒจ ๋˜๋Š” ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ์˜ˆ์™ธ๋ฅผ ์บ์น˜ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
console.error('๋„คํŠธ์›Œํฌ ์š”์ฒญ ์‹คํŒจ ๋˜๋Š” ์˜ˆ์™ธ ๋ฐœ์ƒ:', error);
throw error; // ์˜ˆ์™ธ๋ฅผ ๋‹ค์‹œ throwํ•˜์—ฌ ์ƒ์œ„ ์ฝ”๋“œ๋กœ ์ „ํŒŒํ•ฉ๋‹ˆ๋‹ค.
}
}

const isTokenExpired = (token: string) => {
const decodedPayloadObject = decodeToken(token);
return decodedPayloadObject.exp * 1000 < Date.now();
};

async function updateToken(headers: Headers) {
const response = await refreshToken(headers);
const responseCloned = response.clone();

try {
const newToken = await responseCloned.json();

console.log('newToken:', newToken);

localStorage.setItem('userToken', newToken.accessToken);
} catch (e) {
console.error(e);

return;
}
}

async function withTokenRefresh<T>(callback: () => Promise<T>): Promise<T> {
const userToken = localStorage.getItem('userToken');

if (userToken && isTokenExpired(userToken)) {
console.log('AccessToken ๋งŒ๋ฃŒ๋˜์–ด ์žฌ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค');

const headers: any = {
'content-type': 'application/json',
Authorization: `Bearer ${userToken}`,
};

await updateToken(headers);
}

return callback();
}

import { DEFAULT_PROD_URL } from '../constants';

interface Headers {
'content-type': string;
[key: string]: string;
}
import withTokenRefresh from './utils';

export const getApi = async <T>(url: string) => {
return await withTokenRefresh(async () => {
Expand All @@ -106,18 +13,13 @@ export const getApi = async <T>(url: string) => {
headers['Authorization'] = `Bearer ${userToken}`;
}

console.log('response', DEFAULT_PROD_URL + url);

const response = await fetch(apiUrl, { method: 'GET', headers });

console.log(response);

if (response.status >= 400) {
throw new Error('[SERVER] GET ์š”์ฒญ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}

const responseData: T = await response.json();
console.log('responseData L84๊นŒ์ง€ ์„ฑ๊ณต', responseData);
return responseData;
});
};
70 changes: 32 additions & 38 deletions frontend/src/apis/postApi.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,58 @@
import { DEFAULT_PROD_URL } from '../constants';
import { ContentTypeType } from '../types/Api';

interface Headers {
'content-type': string;
[key: string]: string;
}

interface HeadersForm {
[key: string]: string;
}
import withTokenRefresh from './utils';

export const postApi = async (
url: string,
payload: {} | FormData,
contentType?: ContentTypeType,
) => {
const apiUrl = `${DEFAULT_PROD_URL + url}`;
const userToken = localStorage.getItem('userToken');
return await withTokenRefresh(async () => {
const apiUrl = `${DEFAULT_PROD_URL + url}`;
const userToken = localStorage.getItem('userToken');

if (payload instanceof FormData) {
const headers: any = {};

if (userToken) {
headers['Authorization'] = `Bearer ${userToken}`;
}

const response = await fetch(apiUrl, {
method: 'POST',
headers,
body: payload,
});

if (response.status >= 400) {
throw new Error('[SERVER] POST ์š”์ฒญ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}

return response;
}

if (payload instanceof FormData) {
const headers: HeadersForm = {};
const headers: any = {
'content-type': 'application/json',
};

if (userToken) {
headers['Authorization'] = `Bearer ${userToken}`;
}

if (contentType) {
headers['content-type'] = contentType;
}

const response = await fetch(apiUrl, {
method: 'POST',
headers,
body: payload,
body: JSON.stringify(payload),
});

if (response.status >= 400) {
throw new Error('[SERVER] POST ์š”์ฒญ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}

return response;
}

const headers: Headers = {
'content-type': 'application/json',
};

if (userToken) {
headers['Authorization'] = `Bearer ${userToken}`;
}

if (contentType) {
headers['content-type'] = contentType;
}

const response = await fetch(apiUrl, {
method: 'POST',
headers,
body: JSON.stringify(payload),
});

if (response.status >= 400) {
throw new Error('[SERVER] POST ์š”์ฒญ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}

return response;
};
47 changes: 23 additions & 24 deletions frontend/src/apis/putApi.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,37 @@
import { DEFAULT_PROD_URL } from '../constants';
import { ContentTypeType } from '../types/Api';
interface Headers {
'content-type': string;
[key: string]: string;
}
import withTokenRefresh from './utils';

export const putApi = async (
url: string,
data: {},
contentType?: ContentTypeType,
) => {
const apiUrl = `${DEFAULT_PROD_URL + url}`;
const userToken = localStorage.getItem('userToken');
const headers: Headers = {
'content-type': 'application/json',
};
return await withTokenRefresh(async () => {
const apiUrl = `${DEFAULT_PROD_URL + url}`;
const userToken = localStorage.getItem('userToken');
const headers: any = {
'content-type': 'application/json',
};

if (userToken) {
headers['Authorization'] = `Bearer ${userToken}`;
}
if (userToken) {
headers['Authorization'] = `Bearer ${userToken}`;
}

if (contentType) {
headers['content-type'] = contentType;
}
if (contentType) {
headers['content-type'] = contentType;
}

const response = await fetch(apiUrl, {
method: 'PUT',
headers,
body: JSON.stringify(data),
});
const response = await fetch(apiUrl, {
method: 'PUT',
headers,
body: JSON.stringify(data),
});

if (response.status >= 400) {
throw new Error('[SERVER] PUT ์š”์ฒญ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}
if (response.status >= 400) {
throw new Error('[SERVER] PUT ์š”์ฒญ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
}

return response;
return response;
});
};
Loading

0 comments on commit be5ad68

Please sign in to comment.