refreshToken 적용하기

꾸준히·2025년 6월 18일

PROJECT_REVIEW_SPOTIFY

목록 보기
1/5

로그인을 하려는데, 로그인에 필요한 정보는 다 저장이 되었지만 로그인이 되지 않는 문제가 발생함.
이를 해결하기 위해 refreshToken을 적용

일단, 문제사항이 뭐냐

  1. 로그인 → 사용자 권한까지는 문제 없었음
  2. 사용자 권한 → 필요한 정보들 받아오기까지는 문제 없었음
  3. 정보들 다 받아왔는데 결론: 로그인 안됨 → ❗️ 문제사항 발생

문제사항 발생 이유가 뭐였느냐,

  1. 일단 필요한 정보를 받아오는 부분은 비동기로 실행되는데 렌더가 먼저 되면서 로그인 상태 변경이 반영되지 않았음.
  2. 필요한 정보들은 이미 받아왔는데, useEffect의 조건으로 인해 액세스 토큰을 받아오는 부분을 계속 실행하면서 서버에서는 이미 한 번 사용된 정보로 계속 요청하니까 에러 발생 처리(Invalid authorization code)

그래서 refresh Token 적용함

일단, 필요한 정보들이 뭐냐면

  • ?code
  • access_token

refreshToken을 적용하면서 기존 문제들을 어떻게 해결했느냐

  1. ?code를 한 번 쓰고 다시 못씀 → 로그인 재시도 에러 해결
    : 한 번만 쓰고 나머지는 refresh로 해결
  2. 로그인 상태 유지 어려움(token만료)
    : 자동 갱신
  3. API 요청 전마다 access token 유효성 체크 어려움
    : Axios 인터셉터에서 자동 처리

처리 과정

로그인 버튼 → 사용자 권한 → 권한 승인 후 인증 코드 발급 → 코드로 액세스 및 리프레시 토큰 발급 → 액세스 토큰으로 사용자 정보 받아와 로그인 처리 → 액세스 토큰 만료 시 리프레시 토큰 자동 갱신해서 로그인 유지

토큰 관련 로직 처리

// 액세스 및 리프레시 토큰 발급
const getAccessToken = asyc () => { ... }
const getRefreshToken = asyc () => { ... }

// 액세스 토큰 만료 체크 & 리프레시 로직
export const getValidAccessToken = async () => {
  const accessToken = localStorage.getItem("access_token");
  const refreshToken = localStorage.getItem("refresh_token");
  const expiresAt = parseInt(localStorage.getItem("expires_at") || "0");

  if (Date.now() < expiresAt) {
    return accessToken;
  }

  const refreshed = await getRefreshToken(refreshToken!);
  localStorage.setItem("access_token", refreshed.access_token);
  localStorage.setItem("expires_at", (Date.now() + refreshed.expires_in * 1000).toString());

  return refreshed.access_token;
};
// api.ts
export const api = axios.create({
  baseURL: `${BASE_URL}`,
  timeout: 1000,
  headers: {
    "Content-Type": "application/json",
  },
});

// 요청 인터셉터 추가하기
api.interceptors.request.use(async (request) => {
  const token = await getValidAccessToken();
  request.headers.Authorization = `Bearer ${token}`;

  return request;
});
  • 요청 인터셉터에서 액세스 토큰 만료 여부를 체크하고, 만약 만료되었으면 리프레시 토큰으로 새 액세스 토큰을 받아와서 자동으로 토큰 갱신하도록 함

➕추가 localStorage → sessionStorage로 변경하여 토큰 관리

기존에는 Spotify에서 나온대로 localStorage에 토큰을 저장하였다.
그런데 아무리 사이드 프로젝트라지만 이렇게 두면 안될 것 같아서 sessionStorage에 토큰을 저장하여 관리하는 방식으로 변경했다.

사실 토큰은 쿠키로 관리하는게 제일 안전한데 이 프로젝트는 프론트엔드 only라서 쿠키로는 관리하지 못해 차선책인 sessionStorage로 변경함.

변경 후, 로그인 & 로그아웃 모두 테스트 해본 결과 정상적으로 동작 됨까지 확인함.

0개의 댓글