Dcom-KHU/nearbuy-frontend

로그인 refreshToken cookie 저장 관련 이슈

Closed this issue · 0 comments

<< refreshToken이 browser에 저장되지 않는 오류 >>

✋🏻axios.interceptors를 이용하여, accessToken이 만료 되면, 자동으로 /api/user/token을 호출하여 새 accessToken을 받아오려고 함.
(redux는 새로고침 하면 데이터 없어져서 Cookie에 accessToken 저장시키는 방법을 사용함.)
(아래는 작성한 코드.)

// header에 accessToken 설정
customAxios.interceptors.request.use((config) => {
  const accessToken = GetToken();

  if (!accessToken) {
    config.headers.Authorization = null;
  } else if (accessToken) {
    config.headers.Authorization = `Bearer ${accessToken}`;
  }

  return config;
});

// AccessToken이 만료됐을때 처리
customAxios.interceptors.response.use(
  function (response) {
    return response;
  },
  async function (err) {
    const originalConfig = err.config;

    if (err.response && err.response.status === 401) {
      try {
        const data = await axios.post(`${serverIP}/api/user/token`);
        console.log('data is : ', data);
        if (data) {
          Cookies.set('accessToken', data.data.accessToken, { expires: 1 });
          return await customAxios(originalConfig);
        }
      } catch (err) {
        console.log('토큰 갱신 에러');
      }
      return Promise.reject(err);
    }
    return Promise.reject(err);
  }
);

✋🏻accessToken이 유효한 1분 동안은 /api/user/page를 patch로 했을 때, 유저 정보 수정 정상작동함.
(아래는 patch하는 코드.)

// values는 form 입력값들을 객체로 받은 것.
const formData = {
      name: values.username,
      image: profileImage?.name,
      location: values.location,
    };
    try {
      await customAxios.patch(`/api/user/page`, formData, {
        params: { id: userId },
        headers: {
          Authorization: `Bearer ${token}`,
        },
      });

      global.location.replace('http://localhost:3000/my');
    } catch (err) {
      console.error('edit patch error : ', err);
    }

✋🏻그러나, 1분 뒤, accessToken이 만료 되면, axios 500 error 발생.
accessToken이 만료 되어서 그런 걸로 추정. (근데 왜 401 error가 아닌, 500이 뜨는지 모르겠음.)

✋🏻따라서, interceptors 코드를 이렇게 고치고, refreshToken 요청 시도함.
(error.response.status === 500 일 때, if 문 통과하도록 수정.)
(기존의 accessToken이 있어서 그런 건가 싶어서 Cookies.remove로 제거하고 다시 set 해줌.)
(header에 새로 받은 accessToken 다시 설정해주는 코드 추가.)

if (
      error.response.status === 500 ||
      (error.response.status === 401 && !originalRequest._retry)
    ) {
      originalRequest._retry = true;
      try {
        const response = await axios.post(`${serverIP}/api/user/token`);
        const newAccessToken = response.data.accessToken;
        Cookies.remove('accessToken');
        Cookies.set('accessToken', newAccessToken, { expire: 1 });
        customAxios.defaults.headers.common[
          'Authorization'
        ] = `Bearer ${newAccessToken}`;
        return customAxios(originalRequest);
      } catch (err) {
        console.error('token error : ', err);
      }
    }

    return Promise.reject(error);

✋🏻하지만, /api/user/token에 post 요청을 하면 axis 400 error 발생.
(error message : Required cookie 'refreshToken' for method parameter type Cookie is not present)

✋🏻크롬 개발자 모드의 Application>Cookies를 보면 내가 따로 저장시킨, accessToken과 userId는 존재하지만, refreshToken은 저장되어 있지 않음.

✋🏻postman으로 요청시, /api/user/token post 요청하면 accessToken 정상적으로 반환됨.

✋🏻쿠키 설정 허용 되어있음.

✋🏻withCredentials 옵션을 줘 봤음.

const customAxios: AxiosInstance = axios.create({
  baseURL: secrets.serverIP,
  headers: {
    // "Content-Type": "application/x-www-form-urlencoded",
    // 'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': secrets.serverIP,
  },
  withCredentials: true,
});

✋🏻에러 해결 하지 못함.