Axios Intereptor를 활용하고, refreshToken을 활용해서 acessToken을 재발급 받는 로직을 구현하였다.
보안성 향상
Access token은 상대적으로 짧은 유효 기간을 가지기 때문에, 만료 후 재발급이 필요하다. RefreshToken을 통해 만료된 토큰을 도용하는 것을 방지하고, 자주 재발급을 진행하여 더 안전하게 세션을 관리할 수 있다.
request시, 따로 body로 데이터 전송을 안해주어도 되고, 로그인 시 얻는 Refresh 토큰을 헤더에 Bearer 형태로 넘겨준다.
Authorization: Bearer refreshToken
axiosInstace라는 api hook을 따로 만들어서 코드를 짰다.
import axios from 'axios';
const axiosInstance = axios.create({
baseURL: 'baseurl'
});
axiosInstance.interceptors.request.use(
(config) => {
const token = localStorage.getItem('AccessToken');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
axiosInstance.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
if (error.response?.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
const refreshToken = localStorage.getItem('RefreshToken');
const response = await axios.post('연결된 url', null, {
headers: { Authorization: `Bearer ${refreshToken}` }
});
const { accessToken } = response.data;
localStorage.setItem('AccessToken', accessToken);
originalRequest.headers['Authorization'] = `Bearer ${accessToken}`;
return axiosInstance(originalRequest);
} catch (refreshError) {
console.error('리프레시 토큰 오류:', refreshError);
localStorage.removeItem('AccessToken');
localStorage.removeItem('RefreshToken');
window.location.href = '/login';
return Promise.reject(refreshError);
}
}
return Promise.reject(error);
}
);
export default axiosInstance;
그리고 로그인 부분에 axios.post 대신에 axiosInstance.post로 불러온다. 처음에 로그인에서 불러오지 않아서 코드를 짰음에도 불구하고 제대로 작동되지 않았다.
const response = await axiosInstance.post('/auth/login', {
email: values.email,
password: values.password,
})
이 부분은 User의 정보를 받아오는 부분인데, 맨 처음에 로그인 대신에 유저를 받아오는 부분에서 instance를 사용하였더니 토큰이 재발급이 제대로 진행되지 않았다.
로그인과 유저 정보 받아오는 부분 둘 다! axiosInstance로 받아와야한다.
const response = await axiosInstance.get('/user/me', {
headers: {
Authorization: `Bearer ${token}`
}
});
return response.data;
};