본문 바로가기
Frontend

Axios Interceptor, Lodash.debounce

by 잘먹는 개발자 에단 2025. 4. 15.

어제 개발을 하다가 다음과 같은 문제가 일어났었다.

 

플로우는 다음과 같다.

처음에 로그인을 한다.

로그인을 하면 패스워드를 해싱한다. ( DB에는 원문이 들어가 있지 않고, 단방향 해싱으로 진행한다. )

해싱값을 입력값 ( pw )와 비교한다. 

맞으면 서버에 저장된 SECRET_KEY로 생성한 jwt 토큰을 발급한다.

그리고 이 토큰을 클라이언트측 브라우저의 세션 스토리지에 넣는다. 

이후에, Axios 인스턴스의 헤더에 Authorization : Bearer [토큰] 을 추가해서 API를 날린다.

( 리프레시나 토큰 만료는 아직 고려하지 않았다. ) 

 

문제는 다음에서 발생했다.

토큰을 브라우저의 세션 스토리지에 분명 넣었는데, 

토큰 검증이 되지 않아서 자꾸 401 ( Unauthorized ) 에러가 나는 것이었다. 

리퀘스트를 살펴보니 해당 헤더가 Bearer null로 가고 있었다. 

그러니까 세션 스토리지에 토큰이 추가되는 것이 완료되기 전에 Axios 인스턴스가 가져가려고 했던 건가 

 

원인은 이거여따

Axios의 사용법을 완전하게 숙지하지 않아서 일어난 일이었다.

Axios 인스턴스를 만드는 이유는 어떤 url의 엔드포인트에다가 우리가 http 요청을 쏠 때, 앞에 들어가는 

 

스킴, 호스트주소, 포트를 계속 적어줘야하는데 이건 대부분 겹치기 때문이다.

그래서 이걸 생략하기 위해서 Axios에서는 Instance를 만든다.

 

 

다만, 이 Instance를 만들때는 Interceptor를 알아야하는데, 구글링과 gpt로 알아보자.

** Axios Interceptor ( 이하 인터셉터 )

인터셉터는 요청을 보내거나 받을 때마다 라이브러리가 호출하는 함수이다.

then 또는 catch로 처리되기 전에 요청이나 응답을 가로챌 수 있다.

// ** Request Interceptor **/

axios.interceptors.request.use(
(config) =>{
	// request를 보내기 전에 할 것들
    return config
}, 
(error) => {
	// request가 error가 났을 때 try-catch로부터 catch 되기 전
    return Promise.reject(error);
});



// ** Response Interceptor **/

axios.interceptors.response.use(
(response) => {
	// 200번대의 어떤 상태범위코드 내에 들어오게 되면 여기에서 response를 써서 할 일을 한다.
	return response;
},
(error) => {
	// 200번대의 어떤 에러상태가 들어오면 error로 어떤 상태처리를 사용
    return Promise.reject(error);
}
);

 

 

다음으로 axios interceptor를 삭제할 수도 있다.

const myInterceptor = axios.interceptors.request.use(function({/*..*/});
axios.interceptors.request.eject(myIntercepter);

 

 

** axios Intercepter를 활용해서 로그를 남기면 유용하다.

 

 

** axios Interceptor에서 에러를 가로채서 뭔가 한다음 catch에 넘길 수 있다. 

axios.interceptors.response.use(
	res => {
    	// ~~~~
        return res;
    },
    err => {
    	throw new Error(err.response.data.message);
    }
);


// ** 위와 같이 인터셉터에서 에러를 던지면 아래의 catch의 에러로 던져진다. **/
// ** 즉, catch에서 에러를 받기 전에 처리할 수 있다 **/

const arr = await axios.get(~~~~~~~~).then(~~).catch(err => {})

 

 

 

** axios Interceptor를 활용해서 속도를 제한할 수 있다.

백엔드 리소스는 제한적이며, 많은 비용이 소요될 수 있다. 때문에 http 호출을 속도 제한하여 서버의 부하를 줄일 수 있다.

- 참고로 속도를 제한?? 하는 방법 이외에 일정 단위시간 안의 요청 수를 제한하는 방법도 있다. ( node : rate-limiter )

- 서버측에서 캐싱하는 방법도 있다. 물론 제한적이긴하다.

const debounce = require('lodash.debounce');

axios.interceptors.request.use(
	res => {
    	return new Promise(resolve=>{
        	// 2초마다 request가 호출
            debounce(()=>{
            	return resolve(config)
            }, 2000);
        });
    },
    err => err
);

 

 

 

부록

** Lodash의 debounce

debounce 함수는 어떤 동작 ( 예를 들어 함수호출 )이 연속해서 발생할 때, 마지막 호출 후 일정 시간 ( 예제에서는 2000밀리초, 2초 )이 경과한 후에 단 한번만 실행하도록 한다.

예를 들어서 사용자가 입력필드에 빠르게 타이핑할 때마다 API 호출을 발생시키면 과도한 요청이 발생하는 문제를 방지할 수 있다.

- 장점 : 연속된 호출 합치기 : 여러번 호출되어도 마지막 호출 이후의 대기시간 후 한번만 호출됨

- 사용예 : 이벤트 핸들어, API 호출, 창크기 조절이벤트 등

const debounceFunc = debounce(()=>{
	console.log('실행됨');
}, 2000);


debounce();
debounce();
debounce();

// ** 이렇게 해도 마지막 호출 후 2초 후에 1번 실행됨 **/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Frontend' 카테고리의 다른 글

페이지 단위로 스크롤 끊기  (0) 2025.04.24
글 올라가는 효과  (0) 2025.04.24
css -> tailwind css  (0) 2025.03.28
Recoil-Persist  (0) 2025.03.24
npm, package.json, package-lock.json  (0) 2025.03.18