댕도네냥 프로젝트를 하게되면서 access token 과 refresh token, 두개의 토큰을 다루게 되었다.
JWT 토큰 인증방식은 제 3자에게 토큰 탈취가 쉬워질 수 있고, 이렇게 되면 보안상 취약점이 드러나는 단점이 있기에 토큰 유효기간을 부여하여 보안을 강화한다.
토큰의 유효기간이 짧으면 보안에 뛰어날 수 있겠지만 사용자는 매번 로그인을 다시해야하기에 불편함을 느낀다. 따라서 여기서 사용하는 것이 refresh token을 사용한 토큰 리프레시이다.
우리는 해당 프로젝트에서 다음과 같은 토큰 인증 플로우를 사용했다.
요약하자면 access token 보다 유효기간이 긴 refresh token을 추가하여 access token을 재발급 한다. refresh token이 만료되는 경우에는 다시 로그인을 해야한다.
위 과정을 나는 axios를 사용해 구현했다.
1. axios 기본설정해주기
import axios from "axios";
import { getCookie, setCookie } from "../hook/cookies"
export const instance = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
headers: {
'Content-Type': 'application/json',
withCredentials: true,
},
});
2.interceptors.request 사용해서 헤더 설정해주기
instance.interceptors.request.use((config) =>{
if(!config.headers) return config;
const accesstoken = getCookie("Authorization")
if(accesstoken && config.headers) {
config.headers["Authorization"] = `${accesstoken}`;
}
return config;
})
따로 설정해준 getCookie라는 함수를 통해 쿠키에서 토큰을 가져온다.
이후 config header에 "Authorization"이라는 이름으로 헤더설정을 해준다
3.access toke이 만료된 경우 interceptors.response 를 통해 토큰 재발급하기
instance.interceptors.response.use(
(res)=>{
return res;
},
async (error) => {
if(error.config && error.response && error.response.status === 401){
error.config._retry = true;
const refreshtoken =getCookie("refreshToken");
error.config.headers.RefreshToken=`${refreshtoken}`
return axios.get(`${process.env.NEXT_PUBLIC_API_URL}/auth/me`, {
headers : {
RefreshToken : `${refreshtoken}`,
'Content-Type': 'application/json',
withCredentials: true,
}
}).then( async(res)=>{
if(res.status === 200 && res.data.accessToken){
setCookie("Authorization",res.data.accessToken,{})
const accesstoken = getCookie("Authorization")
error.config.headers["Authorization"] = `${accesstoken}`;
return instance(error.config)}
})
}
return Promise.reject(error)
access token이 만료된 경우 서버에서 401 오류를 돌려주기로 했으므로 해당 조건인경우 리프레시 토큰을 헤더에 담아 주었다.
이후 응답값(재발급된 accesstoken)을 다시 쿠키에 저장하고 헤더로 담는 작업을 했다.