FrontEnd Develop

⏿ 실제 백엔드와 프론트엔드 통신 #3. Axios Instance와 Refresh, Access 토큰 함수

Frisbeen 2025. 1. 24. 20:44

 인터셉터 설정의  포스팅의 다음 단계입니다.

 

 

리프레시 토큰을 사용해 새로운 엑세스 토큰을 발급받는 함수입니다. 요청과 응답 인터셉터에서 사용하는 핵심 로직 중 하나로, 엑세스 토큰이 만료된 경우를 처리하기 위해 만들어진 함수입니다. 이 함수는 토큰 기반 인증 시스템의 중요한 부분입니다. 아래에서 동작 원리와 역할을 설명하겠습니다.

 

1. 이 함수의 역할

1. 엑세스 토큰 갱신:

엑세스 토큰이 만료되면, 기존 리프레시 토큰을 사용해 새로운 엑세스 토큰을 발급받습니다.

새로 발급받은 엑세스 토큰은 이후의 요청에서 사용됩니다.

 

2. 리프레시 토큰도 갱신:

리프레시 토큰 역시 일정 기간 후 만료될 수 있으므로, 서버에서 갱신된 리프레시 토큰이 함께 반환되면 이를 업데이트합니다.

 

3. 인증 상태 유지:

사용자가 다시 로그인하지 않아도 인증 상태를 유지할 수 있도록 도와줍니다.

(사용자 경험 개선)

// 리프레시 토큰으로 액세스 토큰 갱신 함수
const refreshAccessToken = async () => {
  try {
    const refreshToken = localStorage.getItem('refreshToken');
    const accessToken = localStorage.getItem('token');
    if (!refreshToken) {
      throw new Error('Refresh Token이 없습니다.');
    }

    const response = await axios.post(
      '/api/auth/refresh',
      {},
      {
        headers: {
          //시온
          'ACCESS-AUTH-KEY': `BEARER ${accessToken}`,
          'REFRESH-AUTH-KEY': `BEARER ${refreshToken}`,
        },
      }
    );

    const { accessToken: newAccessToken, refreshToken: newRefreshToken } =
      response.data;
    if (newAccessToken) localStorage.setItem('token', newAccessToken);
    if (newRefreshToken) localStorage.setItem('refreshToken', newRefreshToken);

    return newAccessToken;
  } catch (error) {
    console.error(
      '리프레시 토큰 갱신 실패:',
      error.response?.data || error.message
    );
    throw error;
  }
};

 

2. 코드의 주요 동작 설명

 

1) 로컬 스토리지에서 리프레시 토큰과 엑세스 토큰 가져오기 

 

우리가 토큰을 저장했던 로컬스토리지에서 토큰들을 회수합니다.

const refreshToken = localStorage.getItem('refreshToken');
const accessToken = localStorage.getItem('token');
if (!refreshToken) {
  throw new Error('Refresh Token이 없습니다.');
}

 

로컬 스토리지에서 토큰 가져오기: 클라이언트는 서버와 통신하기 위해 로컬 스토리지에서 기존의 refreshTokenaccessToken을 가져옵니다.

 

리프레시 토큰 검증:

만약 리프레시 토큰이 없다면, 토큰 갱신이 불가능하므로 에러를 발생시킵니다.

이 에러는 요청 인터셉터 또는 상위 호출 스택에서 처리됩니다.

 

2) 서버로 갱신 요청 보내기 (헌 집줄게 새 집 다오)

const response = await axios.post(
  '/api/auth/refresh',
  {},
  {
    headers: {
      'ACCESS-AUTH-KEY': `BEARER ${accessToken}`,
      'REFRESH-AUTH-KEY': `BEARER ${refreshToken}`,
    },
  }
);

 

POST 요청:

/api/auth/refresh 엔드포인트로 리프레시 토큰을 보내 새로운 엑세스 토큰을 요청합니다.

이 요청은 헤더에 기존 엑세스 토큰(ACCESS-AUTH-KEY)과 리프레시 토큰(REFRESH-AUTH-KEY)을 포함합니다.

헤더 사용:

백엔드에서 정의한 인증 방식에 따라 헤더에 토큰을 추가하여 요청합니다.

백엔드는 이 토큰들을 검증하고 새 엑세스 토큰을 발급합니다.

 

3) 서버 응답 처리

 

response.data로부터 구조분해할당(기본값 할당)으로 받아옵니다.

const { accessToken: newAccessToken, refreshToken: newRefreshToken } =
  response.data;
if (newAccessToken) localStorage.setItem('token', newAccessToken);
if (newRefreshToken) localStorage.setItem('refreshToken', newRefreshToken);

 

새로운 토큰 저장 (받은 새 집을 다시 로컬스토로지에 저장합니다.)

서버로부터 받은 newAccessTokennewRefreshToken을 로컬 스토리지에 저장합니다.

이렇게 하면 이후 요청에서 갱신된 토큰이 사용됩니다.

 

 

무한 사이클처럼 보이지만 안전장치가 있다

 

1. 리프레시 토큰 유효기간

리프레시 토큰은 일정 시간 후 만료되도록 설정됩니다(예: 7일, 30일 등).

리프레시 토큰이 만료되면 서버는 새로운 토큰을 발급하지 않고, 클라이언트에 로그아웃 처리를 유도합니다. 따라서 무한히 사이클이 이어지지 않습니다.

 

2. 엑세스 토큰 만료 시간

엑세스 토큰은 짧은 유효기간(예: 15분)을 가지며, 보안성을 위해 자주 갱신됩니다.

갱신 작업은 사용자가 애플리케이션을 계속 사용할 때에만 발생합니다(백그라운드 작업).