[React-Native] axios interceptors

DaYoung·2024년 1월 3일

React-Native

목록 보기
14/35

axios intercepter

✔️ axios intercepter?

axios intercepter은 애플리션에서 처리하기 전에 Axios 라이브러리에서 수행한 HTTP요청 or 응답을 가로채고 수정하는데 사용할 수 있는 기능이다.

  • request: 요청을 보내기 전에 가로채서 헤더에 정보를 추가하거나 요청 데이터를 수정하는 등의 작업을 할 수 있음
  • response: 서버에서 받은 응답을 처리하기 전에 가로채서 응답 데이터를 가공하거나, 에러 처리를 수행하는 등의 작업을 할 수 있음

✔️ axios intercepter 사용하는 이유?

  • 오류 처리: 서버에서 오는 에러를 미리 처리할 있다.
  • 인증 관리: 사용자가 로그인한 상태에서 요청을 보낼 때, 토큰이 만료되었는지 체크하고 만료되었다면 새로운 토큰을 요청하여 자동으로 갱신할 수 있다.
  • 데이터 가공: 요청이나 응답의 내용을 변경하거나 추가 작업을 할 수 있다. 예를 들어, 특정 데이터를 요청에 자동으로 추가하거나, 응답에서 필요한 정보만 추출하는 작업이 가능하다.
  • 요청 or 응답에서 동일한 코드를 반복하지 않아도 되어서 코드가 간결해지고 유지 관리가 쉬워진다.

✔️ axios intercepter 사용 예제

request

요청 시 Access Token 보내주기

instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
    config.headers.Accept = 'application/json';

    return AsyncStorage.getItem(StorageKeys.인증_토큰)
        .then((model) => {
            if (model) {
                const tokenModel = JSON.parse(model);

                config.headers.Authorization = `Bearer ${tokenModel.accessToken}`;
            }
            return config;
        })
        .catch(() => {
            return config;
        });
});

response

에러를 처리하는 로직이다.
401이면 accesstoken이 만료되었을 때인데 토큰을 갱신해줘야 한다.
토큰이 만료되었다고 판단하고 local storage 에 있는 refresh token을 전송하여 새로운 access token을 받아온다.
받아온 access token은 기존 local storage에 있는 access token과 교체하여 갱신시켜 준다.
token이 갱신되면 이전 요청을 다시 보내는 과정이 필요하다.

instance.interceptors.response.use((response) => response,
    async (error) => {
        console.log("error", error)
        if (error.response) {
            const { status, data, config } = error.response

            if (status === 403 || data.code === 403) {
                if (data.hasPenalty) {
                    console.log('403', data, config);
                }
            }

            //AccessToken이 만료됐을 때 처리
            if (status === 401) {
                const originalConfig = error.config;

                try {
                    const token = await Storage.getItems(StorageKeys.인증_토큰);
                    if (token) {
                        const tokenModel = JSON.parse(token);

                        //토큰 갱신
                        const data = await axios<UserModel.IJwtTokenModel, any>({
                            url: `/api/auth/update-token`,
                            method: 'GET',
                            headers: {
                                Authorization: tokenModel.refreshToken,
                            },
                        });

                        if (data) {
                            const tokenModel = {
                                accessToken: data.accessToken,
                                refreshToken: data.refreshToken,
                            } as UserModel.IJwtTokenModel;

                            await Storage.setItems(StorageKeys.유저_정보, data);
                            await Storage.setItems(StorageKeys.인증_토큰, tokenModel);

                            return await instance.request(originalConfig);
                        }
                    } else {
                        await Storage.removeItems(StorageKeys.유저_정보);
                        await Storage.removeItems(StorageKeys.인증_토큰);
                    }
                } catch (error) {
                    await Storage.removeItems(StorageKeys.유저_정보);
                    await Storage.removeItems(StorageKeys.인증_토큰);
                }

                // 오류 발생 시 오류 내용 출력 후 요청 거절
                // return Promise.reject(error);
            }

            if (status === 500) {
                console.log('500', data, config);
            }
        }

        return error.response;
    });
profile
안녕하세요. 프론트앤드 개발자 홍다영입니다.

0개의 댓글