React
Refresh Token과 Access Token
code10
2022. 8. 1. 12:10
토큰 유효 시간이 비교적 긴 리프레시 토큰을 활용하여, 시간이 지나도 로그인을 유지할 수 있게 했다. 어떻게 활용했나?
안전한 보안과 사용자 편리성을 위한 로그인 유지를 위해. access 토큰 만료 후 401에러가 떴는데, 이때 refresh 토큰으로 access 토큰을 재발행함으로써 로그인을 유지. 유효 시간을 늘리는 방식이 아닌 토큰 재발행을 활용했다.
1. Refresh Token과 Access Token
1-1. 토큰
토큰 기반 인증 시스템은 클라이언트가 서버에 접속을 하면 서버에서 해당 클라이언트에게 인증되었다는 의미로 '토큰'을 부여한다. 이 토큰은 유일하며 토큰을 발급받은 클라이언트는 또 다시 서버에 요청을 보낼 때 요청 헤더에 토큰을 심어서 보낸다. 그러면 서버에서는 클라이언트로부터 받은 토큰을 서버에서 제공한 토큰과의 일치 여부를 체크하여 인증 과정을 처리하게 된다. 기존의 세션기반 인증은 서버가 파일이나 데이터베이스에 세션정보를 가지고 있어야 하고 이를 조회하는 과정이 필요하기 때문에 많은 오버헤드가 발생한다. 하지만 토큰은 세션과는 달리 서버가 아닌 클라이언트에 저장되기 때문에 메모리나 스토리지 등을 통해 세션을 관리했던 서버의 부담을 덜 수 있다. 토큰 자체에 데이터가 들어있기 때문에 클라이언트에서 받아 위조되었는지 판별만 하면 되기 떄문이다.
(출처:https://inpa.tistory.com/559#Token_인증)
JWT는 발급한 후 삭제가 불가능하기 때문에,
접근에 관여하는 토큰에 유효시간을 부여하는 식으로 탈취 문제에 대해 대응을 하여야 한다.
(출처:https://inpa.tistory.com/entry/WEB-📚-Access-Token-Refresh-Token-원리-feat-JWT)
1-2. JWT
1-2-1. JWT 정의
JWT(JSON Web Token)란 인증에 필요한 정보들을 암호화시킨 JSON 토큰을 의미한다. 그리고 JWT 기반 인증은 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 방식이다 JWT는 JSON 데이터를 Base64 URL-safe Encode 를 통해 인코딩하여 직렬화한 것이며, 토큰 내부에는 위변조 방지를 위해 개인키를 통한 전자서명도 들어있다. 따라서 사용자가 JWT 를 서버로 전송하면 서버는 서명을 검증하는 과정을 거치게 되며 검증이 완료되면 요청한 응답을 돌려준다.
(출처:https://inpa.tistory.com/559#Token_인증)
1-2-2. JWT 장단점
장점
-Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조를 막을 수 있다.
-인증 정보에 대한 별도의 저장소가 필요없다.
-JWT는 토큰에 대한 기본 정보와 전달할 정보 및 토큰이 검증됐음을 증명하는 서명 등 필요한 모든 정보를 자체적으로 지니고 있다.
-클라이언트 인증 정보를 저장하는 세션과 다르게, 서버는 무상태(StateLess)가 된다.
-확장성이 우수하다.
-토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다.
-(쿠키와 차이) OAuth의 경우 Facebook, Google 등 소셜 계정을 이용하여 다른 웹서비스에서도 로그인을 할 수 있다.
-모바일 어플리케이션 환경에서도 잘 동작한다. (모바일은 세션 사용 불가능)
단점
쿠키/세션과 다르게 JWT는 토큰의 길이가 길어, 인증 요청이 많아질수록 네트워크 부하가 심해진다. Payload 자체는 암호화되지 않기 때문에 유저의 중요한 정보는 담을 수 없다. 토큰을 탈취당하면 대처하기 어렵다.
(출처:https://inpa.tistory.com/559#Token_인증)
1-3. Refresh Token 필요성
Access Token은 접근에 관여하는 토큰이고, Refresh Token은 재발급에 관여하는 토큰
Refresh token을 검증하여 Access token을 재발급한다! 아래와 같은 원리!
아래는 코드! axios로 서버와 통신, axios.interceptors를 이용하여 unauthorized 에러인 401 에러를 한 번에 핸들링하였다.
instance.interceptors.response.use(
function (response) {
return response;
},
function (error) {
if (error.response.status === 400) {
window.alert(error.response.data.errorMessage);
} else if (error.response.status === 401) {
const refreshToken = sessionStorage.getItem("refreshToken");
axios
.post(
`${process.env.REACT_APP_API_URL}/member/reissue`,
{
accessToken: token,
refreshToken: refreshToken,
},
{
headers: {
"Content-Type": "application/json",
},
}
)
.then((response) => {
sessionStorage.setItem("token", response.data.accessToken);
sessionStorage.setItem("refreshToken", response.data.refreshToken);
window.location.reload();
})
.catch((error) => {
console.error(error);
sessionStorage.clear();
window.location.replace("/needlogin");
});
(참고)
[WEB] 📚 Access Token & Refresh Token 원리 (feat. JWT)
Access Token과 Refresh Token 이번 포스팅에서는 기본 JWT 방식의 인증(보안) 강화 방식인 Access Token & Refresh Token 인증 방식에 대해 알아보겠다. 먼저 JWT(Json Web Token) 에 대해 잘 모르는 독자들은..
inpa.tistory.com