[React-Native] Axios Request 모듈화를 통한 서버 통신 구현

Seojin Kwak·2024년 5월 21일
0

React Native

목록 보기
4/4

React Native에서는 서버와 통신하기 위해 Axios 라이브러리를 사용한다.
토큰 저장 방식은 react-native-keychain을 사용했다.

react-native-keychain을 활용한 storage 관리

Axios Instance 생성하기

API_URL은 env에 저장해두고 꺼내온다.

const instance = axios.create({
    baseURL: API_URL,
    withCredentials: true,
    timeout: 2000,
});

사용자 지정 config를 넣어 Axios Instance를 생성할 수 있다.

Axios Interceptors 사용하기

  • default header 처리
instance.defaults.headers['Set-Cookie'] = `refresh_token=${refreshToken}`;

refreshToken을 header에 입력한다.

  • request 인터셉터 처리
instance.interceptors.request.use(
    async config => {
      config.headers['Content-Type'] = 'application/json';
      config.headers['Authorization'] = `Bearer ${accessToken}`;
      return config;
    },
    (err: unknown) => {
      Promise.reject(err);
    },
  );

request 요청을 보낼 때, 기본으로 넣을 accessToken을 설정한다.
header를 Axios 인스턴스 생성 시점에 입력할 수도 있지만, 나는 interceptor 단계에서 처리해줬다.

  • response 인터셉터 처리
instance.interceptors.response.use(
    async response => {
      const { config } = response;
      const originalRequest = config;
      if (response.status === 401) { // 401: Unauthorized
        // 토큰 만료 혹은 로그인 정보 없음
        removeAccessToken();
        return await instance
          .post('/users/reissue-token', { // 토큰 재발급
            loginId: loginId,
            refreshToken: refreshToken,
          })
          .then(async res => { // accessToken과 refreshToken 저장
            setAccessToken(res.data.result.accessToken);
            setRefreshToken(res.data.result.refreshToken);
            // 헤더에 새로운 accessToken 입력
            originalRequest.headers.Authorization = `${res.data.result.accessToken}`;
            return axios(originalRequest);
          });
      }
      // 로그인 정보가 있는 경우 (일반 요청)
      return response.data;
    },
    (err: unknown) => {
      Promise.reject(err);
    },
  );

response에서 일괄적으로 401 토큰이 유효하지 않은 Unauthorized 에러가 발생한다면, accessToken을 삭제하고, refreshToken으로 재발급을 요청해 새로운 accessToken을 발급받는다.

Request 모듈화하기

  • request 생성
const instance = createInstance(); // 위에서 생성한 인스턴스를 불러오기

const defaultRequest = async (path: string, body: (url: string) => any) => {
  try {
      const response = body(path);
      return response;
  } catch (err) {
      console.error(err);
  }
};

기본 request 모듈을 만든다.
path: URL path
body: 입력할 data 또는 params

  • 메소드 구현
const post = async (path: string, data: any) => {
    return await defaultRequest(path, async url => {
      const response = (await instance).post(url, data);
      return response;
    });
};

const get = async (path: string, params: any) => {
    return await defaultRequest(path, async url => {
      const response = (await instance).get(url, {
        params: params,
      });
      return response;
    });
};

const patch = async (path: string, data: any) => {
    return await defaultRequest(path, async url => {
      const response = (await instance).patch(url, data);
      return response;
    });
};

Request 모듈 사용하기

  • request 모듈 사용 예시
const request = Request();	// 위에서 정의한 Request 모듈을 불러온다.

const duplicateCheck = async () => {
  const response = await request.post('/users/loginId', {
      loginId: form.loginId,
  });
  if (response.isSuccess) { // 서버에서 isSuccess라는 응답을 준다.
      setCheck({ ...check, loginId: true });
  }
}
profile
Hello, World!

0개의 댓글