프로젝트/COCONOTE

accessToken, refreshToken으로 서버 인증받기

판다꼬마 2023. 8. 25. 23:29
728x90

AcessToken 하나만을 이용한 인증 방식에는 문제점이 있다.

만일 제 3자에게 탈취당할 경우 보안에 취약하다는 점인데 유효기간을 짧게 하여 새롭게 Token을 받아 계속 인증 상태를 업데이트해야 한다. 이렇게 되면 자주 새로운 토큰을 발급받아야 하기 때문에 불편하다. 그래서 유효시간을 길게 하자니 탈취당할 위험에 노출되어 보안이 약해지게 된다.

이렇게 해서 나온 것이 RefreshToken이다.

 

RefreshToken은 AccessToken과 같은 형태의 JWT이다. 처음에 로그인 성공 시 서버에서 AccessToken과 RefreshToken을 내려주게 되는데 AccessToken이 만료가 되면 RefreshToken을 이용해 새로운 AccessToken을 발급받는 형식으로 계속 로그인 상태를 유지할 수 있게 해준다.

아래 사진이 간단하게 요약된 사진이다.

참고: https://supertokens.com/blog/the-best-way-to-securely-manage-user-sessions?s=s

 

1. 로그인 성공

2. AccessToken과 RefreshToken을 발급받아 저장

3. API통신을 할 때 AccessToken을 헤더에 저장하여 요청을 보냄

4. AccessToken을 검증하여 데이터 전송

5. AccessToken 만료

6. 만료된 AccessToken을 헤더에 저장하여 요청

7. 서버에서 검증이 되지 않아 데이터를 받아오지 않음

8. 새로운 AccessToken을 발급받기 위해 RefreshToken를 서버에 보내 새로운 AccessToken 발급

9. 발급받은 새로운 AccessToken을 이용하여 API 통신 진행

 

이런 과정으로 통신이 진행된다.

 

이 과정에서 6~8번 과정을 요청을 보내기 전 자동으로 AccessToken을 발급받는 코드를 작성하였다.

 

 

Axios 인터셉터 적용 이유?

위에서 말한 토큰 인증요청을 필요로 하는 API 통신을 하기 전 401 에러가 발생하면 자동으로 토큰 갱신을 하기 위함, 코드 중복 해결

 

1. Axios 인스턴스 생성

export const instance = axios.create({
  baseURL: BACKEND_URL,
  withCredentials: true,
  headers: { Authorization: `Bearer ${accessToken}` },
});

 

 

2. 응답 인터셉터 추가

axios.interceptors.response.use(
  response => response,
  async error => {
    const requestApi = error.config;

    if (error.response.status === 401 && !requestApi._retry) {
      requestApi._retry = true;
      const refreshToken = getCookie('refreshToken');
      if (refreshToken) {
        try {
          const response = await axios.post(`${BACKEND_URL}/access-tokens`, { refreshToken });

          const accessToken = response.data.accessToken;
          localStorage.setItem('accessToken', accessToken);

          requestApi.headers['Authorization'] = `Bearer ${accessToken}`;
          return axios(requestApi);
        } catch (refreshError) {
          toast.error('사용자 계정 인증 오류입니다. 다시 로그인 해주세요.');
        }
      }
    }

    return Promise.reject(error);
  }
);

 

이렇게 코드를 작성한 후 AccessToken이 만료되면 자동으로 API호출이 되어 새로운 AccessToken을 받아 올 수 있게 되었다.

 

참고

https://supertokens.com/blog/the-best-way-to-securely-manage-user-sessions?s=s 

 

The best way to securely manage user sessions

This blog covers an analysis of a new open source session flow that is secure and easy to integrate.

supertokens.com

 

https://axios-http.com/kr/docs/interceptors

 

인터셉터 | Axios Docs

인터셉터 then 또는 catch로 처리되기 전에 요청과 응답을 가로챌수 있습니다. axios.interceptors.request.use(function (config) { return config; }, function (error) { return Promise.reject(error); }); axios.interceptors.response.use(f

axios-http.com

 

https://leeseong010.tistory.com/133#Axios%20%EC%9D%B8%ED%84%B0%EC%85%89%ED%84%B0%EB%A5%BC%20%EC%A0%81%EC%9A%A9%ED%95%98%EB%A0%A4%EB%8A%94%20%EC%9D%B4%EC%9C%A0%E2%9D%93-1

 

[Axios] Axios 인터셉터 적용하기

인터셉터(Interceptors)란? then 또는 catch로 처리되기 전에 요청과 응답을 가로챌 수 있다. Axios 인터셉터를 적용하려는 이유❓ 토이 프로젝트를 진행하면서 서버에 토큰 인증을 필요로 하는 API 요청

leeseong010.tistory.com

 

728x90