Skip to content

Commit ab4688e

Browse files
committed
refactor: API 변경 사항 수정 반영, 토큰관련 interceptor 문 수정
- API 수정 반영하여 오류 사항들 수정 - 기존 interceptor 문에 오류가 있어서 수정 - AuthCallback Page에서 회원정보 설정 및 우편번호 발급
1 parent eb6cc62 commit ab4688e

File tree

7 files changed

+120
-103
lines changed

7 files changed

+120
-103
lines changed

src/App.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Route, Routes } from 'react-router';
22

3-
import { useAxiosIntercepter } from './apis/client';
43
import useViewport from './hooks/useViewport';
54
import Layout from './layouts/Layout';
65
import MobileLayout from './layouts/MobileLayout';
@@ -27,7 +26,6 @@ import WritePage from './pages/Write';
2726

2827
const App = () => {
2928
useViewport();
30-
useAxiosIntercepter();
3129

3230
return (
3331
<Routes>

src/apis/auth.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,8 @@ export const getUserToken = async (stateToken: string) => {
3636
};
3737

3838
export const getZipCode = async () => {
39-
const { accessToken, userId, zipCode, isLoggedIn } = useAuthStore.getState();
40-
4139
try {
42-
const response = await client.get(`/members/zipCode`, {
43-
headers: {
44-
Authorization: `Bearer ${accessToken}`,
45-
},
46-
});
47-
if (!response) throw new Error('getZipCode: no response data');
48-
console.log(response);
49-
console.log('UserInfo', 'Id:', userId, 'isLoggedIn:', isLoggedIn, 'zipCode', zipCode);
40+
const response = await client.post(`/api/members/zipCode`);
5041
return response;
5142
} catch (error) {
5243
console.error(error);
@@ -56,9 +47,29 @@ export const getZipCode = async () => {
5647
export const getNewToken = async () => {
5748
try {
5849
const response = await client.get('/api/reissue', { withCredentials: true });
50+
if (!response) throw new Error('getNewToken: no response data');
51+
return response;
52+
} catch (error) {
53+
console.error(error);
54+
}
55+
};
56+
57+
export const getMydata = async () => {
58+
try {
59+
const response = await client.get('/api/members/me');
5960
if (!response) throw new Error('getNewTOken: no response data');
6061
return response;
6162
} catch (error) {
6263
console.error(error);
6364
}
6465
};
66+
67+
export const deleteUserInfo = async () => {
68+
try {
69+
const response = await client.delete('/api/members/me');
70+
if (!response) throw new Error('deleteUserInfo: no response');
71+
return response;
72+
} catch (error) {
73+
console.error(error);
74+
}
75+
};

src/apis/client.ts

Lines changed: 44 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import axios from 'axios';
2-
import { useLayoutEffect } from 'react';
32

43
import useAuthStore from '@/stores/authStore';
54

@@ -11,57 +10,51 @@ const client = axios.create({
1110

1211
// eslint-disable-next-line react-hooks/rules-of-hooks
1312

14-
export const useAxiosIntercepter = () => {
15-
const { accessToken, setAccessToken } = useAuthStore();
16-
const authIntercepter = client.interceptors.request.use(
17-
(config) => {
18-
config.headers.Authorization =
19-
accessToken && !config.headers['x-retry']
20-
? `Bearer ${accessToken}`
21-
: config.headers.Authorization;
22-
return config;
23-
},
24-
(error) => {
25-
return Promise.reject(error);
26-
},
27-
);
28-
29-
const refreshInterceptor = client.interceptors.response.use(
30-
(response) => response,
31-
async (error) => {
32-
const originalRequest = error.config;
33-
34-
if (
35-
(error.response.status === 401 || error.response.status === 403) &&
36-
error.response.data.message === 'Unauthorized'
37-
) {
38-
try {
39-
const response = await getNewToken();
40-
setAccessToken(response?.data.accessToken);
41-
42-
originalRequest.headers.Authorization = `Bearer ${response?.data.accessToken}`;
43-
originalRequest.headers['x-retry'] = true;
44-
45-
return client(originalRequest);
46-
} catch {
47-
setAccessToken('');
13+
client.interceptors.request.use(
14+
(config) => {
15+
const { accessToken } = useAuthStore.getState();
16+
if (config.url !== '/auth/reissue' && accessToken) {
17+
config.headers.Authorization = `Bearer ${accessToken}`;
18+
}
19+
return config;
20+
},
21+
(error) => {
22+
return Promise.reject(error);
23+
},
24+
);
25+
26+
client.interceptors.response.use(
27+
(response) => response,
28+
async (error) => {
29+
const { setAccessToken, logout } = useAuthStore.getState();
30+
const originalRequest = error.config;
31+
32+
if (
33+
error.response.status === 401 ||
34+
error.response.status === 403 ||
35+
error.response.data.message === 'Unauthorized'
36+
) {
37+
originalRequest._retry = true;
38+
try {
39+
const response = await getNewToken();
40+
const newToken = response?.data.accessToken;
41+
if (!newToken) {
42+
logout();
43+
window.location.replace('/login');
44+
return Promise.reject(error);
4845
}
49-
}
50-
return Promise.reject(error);
51-
},
52-
);
53-
54-
useLayoutEffect(() => {
55-
return () => {
56-
client.interceptors.request.eject(authIntercepter);
57-
};
58-
}, [accessToken]);
5946

60-
useLayoutEffect(() => {
61-
return () => {
62-
client.interceptors.response.eject(refreshInterceptor);
63-
};
64-
}, [accessToken]);
65-
};
47+
setAccessToken(newToken);
48+
originalRequest.headers.access = newToken;
49+
return client(originalRequest);
50+
} catch (error) {
51+
logout();
52+
window.location.replace('/login');
53+
return Promise.reject(error);
54+
}
55+
}
56+
return Promise.reject(error);
57+
},
58+
);
6659

6760
export default client;

src/main.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ queryClient.setDefaultOptions({
1515
});
1616

1717
createRoot(document.getElementById('root')!).render(
18-
<StrictMode>
19-
<QueryClientProvider client={queryClient}>
20-
<BrowserRouter>
21-
<App />
22-
</BrowserRouter>
23-
</QueryClientProvider>
24-
</StrictMode>,
18+
// <StrictMode>
19+
<QueryClientProvider client={queryClient}>
20+
<BrowserRouter>
21+
<App />
22+
</BrowserRouter>
23+
</QueryClientProvider>,
24+
// </StrictMode>,
2525
);

src/pages/Auth/index.tsx

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,62 @@
1+
/* eslint-disable @typescript-eslint/no-unused-expressions */
12
import { useEffect } from 'react';
23
import { useNavigate } from 'react-router';
34

4-
import { getUserToken } from '@/apis/auth';
5+
import { getUserToken, getMydata, deleteUserInfo, getZipCode } from '@/apis/auth';
56
import useAuthStore from '@/stores/authStore';
67

78
const AuthCallbackPage = () => {
89
const stateToken = new URLSearchParams(window.location.search).get('state');
910
const redirectURL = new URLSearchParams(window.location.search).get('redirect');
1011

11-
const { setUserId, setZipCode, setAccessToken, zipCode } = useAuthStore();
12+
const { setZipCode, setAccessToken, login } = useAuthStore();
1213

1314
const navigate = useNavigate();
1415

1516
const setUserInfo = async (stateToken: string) => {
1617
try {
17-
const userInfo = await getUserToken(stateToken);
18-
if (!userInfo) throw new Error('Error Fetching userInfo');
18+
const response = await getUserToken(stateToken);
19+
if (!response) throw new Error('Error Fetching userInfo');
1920

20-
const accessToken = userInfo.match(/Bearer\s+(\S+)/);
21-
if (accessToken) setAccessToken(accessToken[1]);
22-
console.log('token', accessToken);
21+
const userInfo = response.data;
22+
if (userInfo) {
23+
login();
24+
userInfo.accessToken && setAccessToken(userInfo.accessToken);
2325

24-
const userId = userInfo.match(/UserId=(\d+)/);
25-
if (userId) setUserId(userId[1]);
26+
if (redirectURL == 'home') {
27+
const zipCodeResponse = await getMydata();
28+
if (!zipCodeResponse) throw new Error('Error Fetching userInfo');
29+
const zipCode = zipCodeResponse.data.data.zipCode;
30+
zipCode && setZipCode(zipCode);
2631

27-
const zipCode = userInfo.match(/ZipCode=([A-Za-z0-9]+)/);
28-
if (zipCode) setZipCode(zipCode[1]);
32+
console.log(
33+
'isLoggedIn',
34+
useAuthStore.getState().isLoggedIn,
35+
'access',
36+
useAuthStore.getState().accessToken,
37+
'zipCode',
38+
useAuthStore.getState().zipCode,
39+
);
40+
} else if (redirectURL === 'onboarding') {
41+
const createZipCodeResponse = await getZipCode();
42+
if (!createZipCodeResponse) throw new Error('Error creating ZipCode');
43+
const zipCode = createZipCodeResponse.data.data.zipCode;
44+
const newAccessToken = createZipCodeResponse.headers['authorizazion'];
45+
46+
setZipCode(zipCode);
47+
setAccessToken(newAccessToken);
48+
}
49+
} else {
50+
navigate('/login');
51+
}
2952
} catch (error) {
3053
console.error(error);
3154
}
3255
};
3356

3457
// const redirection = () => {
35-
// if(redirectURL === 'onboarding') navigate('/onboarding');
36-
// else if(redirectURL === 'home') navigate('/');
58+
// if (redirectURL === 'onboarding') navigate('/onboarding');
59+
// else if (redirectURL === 'home') navigate('/');
3760
// else navigate('/notFound');
3861
// };
3962

@@ -44,7 +67,16 @@ const AuthCallbackPage = () => {
4467
}
4568
// else navigate('/notFound');
4669
}, []);
47-
return <div></div>;
70+
71+
const handleLeave = async () => {
72+
try {
73+
const response = await deleteUserInfo();
74+
console.log(response);
75+
} catch (error) {
76+
console.error(error);
77+
}
78+
};
79+
return <button onClick={() => handleLeave()}>탈퇴</button>;
4880
};
4981

5082
export default AuthCallbackPage;

src/pages/Onboarding/SetZipCode.tsx

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { useEffect, useState } from 'react';
22

3-
import { getZipCode } from '@/apis/auth';
43
import useAuthStore from '@/stores/authStore';
54

65
import Spinner from './components/Spinner';
@@ -10,22 +9,10 @@ const SetZipCode = ({
109
}: {
1110
setIsZipCodeSet: React.Dispatch<React.SetStateAction<boolean>>;
1211
}) => {
13-
const [zipCode, setZipCode] = useState<string>('');
1412
const [isBtnActive, setIsBtnActive] = useState<boolean>(false);
15-
const { accessToken } = useAuthStore.getState();
13+
const { zipCode } = useAuthStore.getState();
1614

17-
const fetchZipCode = async () => {
18-
try {
19-
const response = await getZipCode(accessToken as string);
20-
if (!response) throw new Error('fetchZipCode: no response');
21-
console.log(response.data.zipCode);
22-
setZipCode(response.data.zipCode);
23-
} catch (error) {
24-
console.error(error);
25-
}
26-
};
2715
useEffect(() => {
28-
fetchZipCode();
2916
setTimeout(() => {
3017
setIsBtnActive(true);
3118
}, 6300);

src/stores/authStore.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ import { persist, createJSONStorage } from 'zustand/middleware';
33

44
interface AuthStore {
55
isLoggedIn: boolean;
6-
userId: number | null;
76
zipCode: string;
87
accessToken: string;
98
login: () => void;
109
logout: () => void;
11-
setUserId: (userId: number) => void;
1210
setZipCode: (zipCode: string) => void;
1311
setAccessToken: (accessToken: string) => void;
1412
}
@@ -17,11 +15,9 @@ const useAuthStore = create(
1715
(set) => ({
1816
isLoggedIn: false,
1917
accessToken: '',
20-
userId: null,
2118
zipCode: '',
2219
login: () => set({ isLoggedIn: true }),
23-
logout: () => set({ isLoggedIn: false, userId: null, zipCode: '' }),
24-
setUserId: (userId) => set({ userId: userId }),
20+
logout: () => set({ isLoggedIn: false, zipCode: '', accessToken: '' }),
2521
setZipCode: (zipCode) => set({ zipCode: zipCode }),
2622
setAccessToken: (accessToken) => set({ accessToken: accessToken }),
2723
}),

0 commit comments

Comments
 (0)