This commit is contained in:
41
src/api/attachInterceptors.js
Normal file
41
src/api/attachInterceptors.js
Normal file
@ -0,0 +1,41 @@
|
||||
import { refreshAccessToken } from './tokenUtils';
|
||||
|
||||
export const attachAuthInterceptors = (axiosInstance) => {
|
||||
// 요청 시 access token 자동 첨부
|
||||
axiosInstance.interceptors.request.use(config => {
|
||||
const token = localStorage.getItem('access');
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
// 응답 시 access 만료 → refresh 재시도
|
||||
axiosInstance.interceptors.response.use(
|
||||
res => res,
|
||||
async err => {
|
||||
const originalRequest = err.config;
|
||||
|
||||
if (
|
||||
err.response?.status === 401 &&
|
||||
!originalRequest._retry &&
|
||||
localStorage.getItem('refresh')
|
||||
) {
|
||||
originalRequest._retry = true;
|
||||
|
||||
try {
|
||||
const newAccess = await refreshAccessToken();
|
||||
originalRequest.headers.Authorization = `Bearer ${newAccess}`;
|
||||
return axiosInstance(originalRequest);
|
||||
} catch (refreshError) {
|
||||
console.error('토큰 갱신 실패', refreshError);
|
||||
localStorage.removeItem('access');
|
||||
localStorage.removeItem('refresh');
|
||||
window.location.href = '/login'; // 또는 useNavigate 사용 가능
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(err);
|
||||
}
|
||||
);
|
||||
};
|
@ -1,20 +1,12 @@
|
||||
// src/api/authApi.js
|
||||
import axios from 'axios';
|
||||
import { attachAuthInterceptors } from './attachInterceptors';
|
||||
|
||||
const authApi = axios.create({
|
||||
baseURL: process.env.REACT_APP_API_AUTH,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
// JWT 자동 포함 (로그인 이후 /me 호출 등에 사용 가능)
|
||||
authApi.interceptors.request.use(config => {
|
||||
const token = localStorage.getItem('access');
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
attachAuthInterceptors(authApi);
|
||||
|
||||
export default authApi;
|
||||
|
@ -1,20 +1,12 @@
|
||||
// src/api/blogApi.js
|
||||
import axios from 'axios';
|
||||
import { attachAuthInterceptors } from './attachInterceptors';
|
||||
|
||||
const blogApi = axios.create({
|
||||
baseURL: process.env.REACT_APP_API_BLOG,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
// 게시글 작성 시에도 JWT 필요하므로 interceptor 동일하게 구성
|
||||
blogApi.interceptors.request.use(config => {
|
||||
const token = localStorage.getItem('access');
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
attachAuthInterceptors(blogApi);
|
||||
|
||||
export default blogApi;
|
||||
|
@ -1,20 +1,12 @@
|
||||
// src/api/todoApi.js
|
||||
import axios from 'axios';
|
||||
import { attachAuthInterceptors } from './attachInterceptors';
|
||||
|
||||
const todoApi = axios.create({
|
||||
baseURL: process.env.REACT_APP_API_TODO,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
// JWT 자동 첨부
|
||||
todoApi.interceptors.request.use(config => {
|
||||
const token = localStorage.getItem('access');
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
attachAuthInterceptors(todoApi);
|
||||
|
||||
export default todoApi;
|
||||
|
16
src/api/tokenUtils.js
Normal file
16
src/api/tokenUtils.js
Normal file
@ -0,0 +1,16 @@
|
||||
import axios from 'axios';
|
||||
|
||||
export const refreshAccessToken = async () => {
|
||||
const refreshToken = localStorage.getItem('refresh');
|
||||
|
||||
if (!refreshToken) throw new Error('No refresh token');
|
||||
|
||||
const res = await axios.post(
|
||||
`${process.env.REACT_APP_API_AUTH}/api/auth/token/refresh/`,
|
||||
{ refresh: refreshToken }
|
||||
);
|
||||
|
||||
const newAccess = res.data.access;
|
||||
localStorage.setItem('access', newAccess);
|
||||
return newAccess;
|
||||
};
|
Reference in New Issue
Block a user