#1. axios interceptor 사용하기

로그인 기능을 구현할 때 주로 토큰 기반 인증으로 구현하게 되는데, 이 때 JWT(Json Web Token) 많이 사용한다.

토큰 인증 방식은 좋은 방법이긴 하나 제 3자에게 토큰이 노출되었을 경우 보안에 취약하다는 단점이 있다.

그래서 토큰 인증을 구현할 때 유효기간을 짧게 설정한 accessToken으로 인증하고, 이 accessToken이 만료 되었을 때, 유효기간을 길게 설정한 refreshToken을 통해 accessToken을 재발급 받는다.

refreshToken 마저 만료되었을 경우 다시 로그인 하여 재발급 받는다.

여기까지가 JWT에 대한 간단한 설명이고,

 

그렇다면 토큰 인증을 받기 위해 클라이언트에 저장된 토큰을 서버로 보내야 하는데 어떻게 보내야 할까?

심지어 이 과정이 로그인 시 이루어져야 한다.

로그인 할 때 이루어지려면 비동기 통신 시 토큰 정보를 보내야 한다는 것인데.. 이에 대한 답은 axios interceptor 였다.

 

axios interceptor 란?

axiois interceptor는 비동기 통신이 이루어지기 전에 요청(request)이나 응답(response)을 가로채 작업을 추가로 수행한 뒤 통신이 이루어지게 하는 기능이다.

axios interceptor는 로그인 시 토큰 인증할 때만 사용하는건 아니지만, 토큰 인증시 요청을 보낼 때 header에 access 토큰을 함께 실어 보내고, 응답 받을 때 에러가 발생(accessToken 만료)하면 refresh 토큰을 확인하여 재발급을 요청한다.

  • 요청(request) interceptor
import axios from 'axios';

// 요청(request) interceptor
axios.interceptors.request.use(
  function (request) {
    // 요청을 보내기 전 수행할 작업
    return request;
  },
  function (error) {
    // 에러에 대한 처리
    return Promise.reject(error);
  }
);

export default axios;
  • 응답(response) interceptor
import axios from 'axios';

// 응답(response) interceptor
axios.interceptors.response.use(
  function (response) {
    // 200대 response를 받아 응답 데이터를 가공하는 작업
    return response;
  },
  function (error) {
    // 200대 이외의 에러 응답을 가공
    return Promise.reject(error);
  }
);

export default axios;

 

1. 요청시 토큰 보내기

axios.interceptors.request.use(
  (request) => {
    // 세션스토리지에 저장되어 있는 access 토큰을 header에 저장 
    request.headers['토큰이름'] = window.sessionStorage.getItem('accessToken');
    return request;
  },
  (error) => {
    return Promise.reject(error);
  }
);
  • 서버에 request 보낼 때 클라이언트에 저장되어 있는 토큰 정보를 header를 통해 보낸다.
  • 토큰 저장은 꼭 세션스토리지에 하지 않아도 된다.

 

2. 응답시 토큰 확인

axios.interceptors.response.use(
  (response) => {
    return response;
  },
  async (error) => {
    const { response, config } = error;
	
    // 응답 받은 상태 코드가 401이라면
    if (response.status === 401) {
      const { data } = await axios.get('api주소', {
        baseURL: 'url 주소',
        params: {
          // refresh 토큰으로 재발급 요청
          token: window.sessionStorage.getItem('refreshToken'),
        },
      });

      const { accessToken } = data;
      //새 액세스 토큰을 세션스토리지에 저장
      window.sessionStorage.setItem('accessToken', accessToken);
      //새 액세스 토큰을 헤더에 설정
      config.headers['access-token'] = accessToken;
      //재요청
      return await axios(config);
    }
    return Promise.reject(error);
  }
);
  • access 토큰이 만료되어 서버에서 401 에러를 보내면 refresh 토큰을 다시 서버에 보내 재발급 요청을 한다.
  • 재발급 받은 access 토큰을 다시 세션스토리지에 저장(꼭 세션스토리지가 아니여도 된다)하고, header에 바뀐 access 토큰을 저장한다.

 

3. axios 사용

import axios from '../config/axios';
  • axios를 사용하고자 하는 컴포넌트에 기존 axios 대신 interceptor가 적용된 axios를 호출하여 사용한다.

 

 

jwt 인증 과정은 백엔드와의 교류가 있어야 가능하기 때문에 여기서는 간단하게 사용 방법만 확인해 보았다.

+ Recent posts