jwt token 관리

모성종·2024년 3월 13일
0

로그인 시 발급되는 jwt token 관리
우리 프로덕트는 10분의 jwt 유효기간을 두고,
만약 유효기간이 지난 jwt 를 포함한 요청을 보낸다면 서버에서 HTTP status 401 응답을 주기로 했다.

토큰 갱신 방법에는 클라이언트에서 능동적으로 요청하는 방식을 차용할 수도 있고,
서버에서 해당 토큰이 만료됐다고 알려주는 방식으로 구현할 수도 있다.

우리는 API 요청에 포함된 토큰이 만료됐는지 서버에서 체크하여 응답으로 주는 방식으로 구현하기로 했고,
만료된 토큰에 대해서도 두 가지 케이스로 나눴다.
1. 만료된지 얼마 안돼서 갱신할 수 있는 토큰
2. 만료된지 오랜시간이 지나 더이상 사용할 수 없는 토큰

토큰을 갱신하는 케이스

1번 케이스에서는 API 요청에 대한 응답이 정상응답이 아니라 토큰갱신이 필요하다는 응답코드를 내려받는다.
해당 응답을 받았을 경우 axios interceptor 에서 token refresh 요청을 만료된토큰과 함께 서버로 요청한다.
서버에서는 갱신된 새로운 토큰을 응답으로 주고 해당 토큰을 클라이언트에서 새로 저장 후 이전에 실패한 원래 API요청을 다시 보낸다.

import React, { useEffect } from "react";
import axios from "axios";

interface Props {
  children: React.JSX;
}
function Authentication(props: Props) {
  const { children } = props;
  
  useEffect(() => {
    const interceptor = axios.interceptors.response.use(
      (response) => response, 
      async (error) => {
        if (error.response?.status === 401) {
            if (error.response.data.response_code === "토큰만료됨") {
              navigate("/login");
            }
            if (error.response.data.response_code === "토큰갱신필요") {
              const origin = error.config; // 직전 axios 요청객체
              const resp = await refreshToken();
              
              if (resp.response.data.response_code === "토큰갱신완료") {
                setToken(resp.data.content.token); // 신규토큰으로 교체
                return axios.request(origin); // 직전 axios 요청 다시 보냄
              } else {
                return Promise.reject(error); // 토큰갱신 실패
              }
            }
        }
        return Promise.reject(error);
      });
  }, []);
  
  return <>{children}</>
}

토큰을 갱신할 수 없는 케이스

2번 케이스에서는 해당 토큰은 갱신요청할 수 없고 더이상 쓸 수 없는 토큰이기 때문에 클라이언트에서도 모두 삭제 처리 후 로그인페이지로 사용자를 이동시킨다.

profile
FE Developer

0개의 댓글