이번 캡스톤디자인에서는 서버가 DB백엔드 서버, AI 서버 두개로 나뉘고 토큰도 두 서버가 각각의 토큰이 필요한 상황이어서 axios의 인스턴스 기능과 Interceptors를 이용해서 각각의 서버에 맞게 설정하여줬다.
Axios
- axios는 Promise 기반의 HTTP 클라이언트 라이브러리
- fetch 보다 인터셉트, 자동 json 변환 등 더 많은 기능을 지원한다.
import axios from "axios";
axios.get("/api/users")
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.error(error);
});
Axios 인스턴스
공통 설정을 가진 axios 객체를 따로 만들 수 있음
프로젝트에서 여러 API 엔드포인트를 쓸 때, 인스턴스를 나눠서 사용하면 관리가 편하다.
const instance = axios.create({
baseURL: "https://example/api", // ✅ 본인의 API 서버 주소로 변경
headers: {
"Content-Type": "application/json",
},
timeout: 5000,
});
instance라는 이름을 가진 인스턴스를 만들어 주었다.
해당 API는 api 라는 엔드포인트를 공통으로 가지는 곳에 사용
Axios Interceptors
요청이나 응답을 가로채서 가공할 수 있는 기능
모든 요청/응답에 공통적으로 처리해야 할 일이 있을 때 주로 사용
장점: 매 api 호출마다 토큰을 붙이거나 에러 처리를 할 필요가 없다!
interceptors에서 한번에 설정하면 해결
axios interceptors를 사용하기 전
axios.get("/users", {
headers: {
Authorization: "Bearer YOUR_TOKEN_HERE",
"Content-Type": "application/json"
}
});
axios.post("/users",
{ name: "지원" },
{
headers: {
Authorization: "Bearer YOUR_TOKEN_HERE"
}
}
);
이런식으로 매 요청마다 헤더를 일일히 넣어줘야 하는 번거로움이 생긴다.
axios interceptors 사용하기
// ✅ 요청 전에 토큰 자동 추가
instance.interceptors.request.use(
(config) => {
const token = localStorage.getItem("access_token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// ✅ 응답 에러 핸들링
instance.interceptors.response.use(
(response) => response,
(error) => {
if (error.response) {
// 401 에러 처리 (토큰 만료 등)
if (error.response.status === 401) {
localStorage.removeItem("access_token");
window.location.href = "/login";
}
return Promise.reject(error.response.data);
}
return Promise.reject(error);
}
);
| 인스턴스 헤더 | 인터셉터 헤더 |
| 인스턴스 만들 때 1번만 | 요청이 발생할 때마다 |
| 항상 동일한 값만 적용 | 동적으로 값이 변하는 헤더에 적합 |
실제 활용해보기
이번 캡스톤 디자인에서는 두 서버의 엔드포인트가 달랐기 때문에 2개의 axios instance를 만들어주었다.
기본 서버는 instance, AI 서버는 dailyInstance라고 각각 만들어주어서 따로 관리하였다.
const dailyInstance = axios.create({
baseURL: "https://example",
headers: { "Content-Type": "application/json" },
withCredentials: false,
timeout: 15000,
});
그리고 AI 서버와 백엔드 서버가 쓰는 토큰이 달라서 각 두 토큰을 받아오는 것을 분리해줄 필요가 있었다.
dailyInstance.interceptors.request.use((config) => {
const aijwt = localStorage.getItem("ai_jwt_token");
if (aijwt) config.headers.Authorization = `Bearer ${aijwt}`;
return config;
});
그래서 AI서버와 통신하기 위해서는 dailyInstance를 앞에 붙이고 백엔드와 통신하는 api는 instance를 앞에 붙여서 구분해주었다.
예시)
export const postDiary = (diary_date, category, title, body) => {
return axios.post("/diaries/", {
diary_date,
category,
title,
content: body,
});
};
export const startDailyDiary = () => {
return dailyInstance.get(`/start`);
};
'Develop > FE' 카테고리의 다른 글
| [React] Redux Thunk, Redux Persist (0) | 2025.05.26 |
|---|---|
| React + PWA + Vite 프로젝트 시작하기 (feat. tailwind) (0) | 2025.04.19 |
| [React] fragments, forward props, 여러 JSX 슬롯 활용법 (1) | 2024.11.29 |
| [React] Context (1) | 2024.11.12 |
| [React] Lists and Keys & Forms & Lifting State Up (1) | 2024.10.08 |