JWT Access Token을 사용한 웹 어플리케이션에서 서버로 API를 요청할 때마다 Access Token을 담아서 보내야 하는데, 이때 Access Token이 만료된 경우 Refresh Token을 이용한 Access Token의 갱신이 필요하다.
처음 화면 로딩 시 메뉴에 로그인 정보를 표시해준다거나, 화면을 새로고침 하거나, 사용자가 특정 화면을 열어 놓고 한참 지나서 데이터를 조회하려고 하는 경우 등을 고려해서 언제든 서버로 API 요청 시 항상 Access Token의 유효성을 체크해서 만료 시 Refresh Token을 이용해서 자동으로 Access Token을 갱신하는 스크립트를 작성 해 봤다.
특별한 아니고 Javascript/jQuery Ajax를 이용해서 API를 서버에 요청해 보고 권한 에러 시 자동으로 refresh API를 호출해서 갱신 후 다시 원래 사용하려던 API를 다시 호출해주는 로직이다.
[참고] 아래 소스코드는 서버에서 Token 발급 시 HTTP Only 쿠키(Cookie)에 Access Token 및 Refresh Token를 저장해 둔 상태이다.
사용 방법 (HTML 화면)
<script src="/js/common.js"></script>
<script>
$(function () {
getNoticeList()
});
function getNoticeList(){
var reqBody = {};
reqBody.item = something;
sendXMLHttpRequest("GET", "/board/notice/list", $.param(reqBody), sNoticeList, COM_AjaxFailCallBack);
}
var sNoticeList = function sNoticeListCallBack(list){
console.log(list);
}
</script>
공지사항 목록을 불러오는 화면을 예로 설명해 보면, HTML 화면에서 페이지 로딩이 모두 끝난 후 위와 같이 getNoticeList() 함수를 호출해서 서버에 저장되어 있는 공지사항 목록을 불러오는 API를 호출한다.
이때 sendXMLHttpRequest()라는 공통 함수를 사용해서 API를 호출하면/board/notice/list 라는 API 요청 시 Access Token이 만료되었더라도 자동으로 토큰을 갱신한 뒤 다시 /board/notice/list API를 호출한다.
sNoticeList는 /board/notice/list 가 정상적으로 데이터를 불러온 경우에 수행되는 callback 함수이며, COM_AjaxFailCallBack 함수는 에러가 난 경우 공통적으로 수행하는 Callback 함수다. 상황에 맞게 공통으로 쓰거나 sNoticeList와 같이 화면별로 다르게 callback 함수를 만들어서 사용할 수도 있다.
공통 AJAX Reqeust 함수 (common.js)
function sendXMLHttpRequest(type, url, rq, successCallBack, failCallBack){
$.ajax({
type : type,
contentType: "application/json;charset=UTF-8",
dataType: "json",
url : url,
data : rq,
success : function(data){
successCallBack(data);
},
error: function(xhr, statusText, err){
if(xhr.status == 401){
if(xhr.responseJSON.code == "[Custom Business Error Code]"){
$.ajax({
type : "POST",
contentType: "application/json;charset=UTF-8",
dataType: "json",
url : "/auth/v2/token/refresh",
success : function(data){
$.ajax({
type : type,
contentType: "application/json;charset=UTF-8",
dataType: "json",
url : url,
data : rq,
success : function(data){
successCallBack(data);
},
error: function(xhr, statusText, err){
failCallBack(xhr);
}
});
},
error: function(xhr, statusText, err){
Swal.fire("인증 오류", xhr.responseJSON.message, "warning").then(function(){
location.href = "/login";
});
}
});
}else{
Swal.fire("시스템 오류", "인증 서비스 접속에 실패했습니다.", "warning").then(function(){
location.href = "/login";
});
}
}else{
failCallBack(xhr);
}
}
});
}
최대 3번의 ajax 요청을 보내게 되며, 흐름은 아래와 같다.
- 모든 ajax 요청을 보낼 때 위 함수를 통해 사용.
- 서버에서 Access Token이 유효하다고 판단한 경우 바로 정상 응답.
- 서버에서 401 에러를 준 경우 중 서버가 지정한 커스텀 비즈니스 에러코드가 반환된 경우, Access Token이 유효하지 않은 것으로 판단
- 위 경우 ajax로 access token 갱신 요청 API를 호출 (url : "/auth/v2/token/refresh")
- Refresh에 성공한 경우, 다시 처음 요청한 Endpoint로 API 요청
공통 Error Callback 함수 (common.js)
var COM_AjaxFailCallBack = function ajaxFailCallBack(data){
if(data.responseJSON != null){
Swal.fire("데이터 조회 실패", data.responseJSON.exception_message, "warning");
}else{
Swal.fire("데이터 조회 실패", "서버에서 데이터를 불러오지 못했습니다.", "warning");
}
}
'개발 기록 > Javascript' 카테고리의 다른 글
SVG 움직이는 화살표 with yarrow.js - 예제 소스코드 (0) | 2023.06.06 |
---|---|
[Javascript] 정규식 공백 제거, 사업자 번호 검증, 숫자를 한글 금액으로 (0) | 2023.05.23 |
Javascript 키코드 특정 키 입력 방지 (0) | 2023.05.22 |
[Javascript] 페이징 소스코드 - jQuery, Ajax, and Bootstrap5 (0) | 2023.05.22 |
[Javascript] 팝업창 만들기 - Window.open() (0) | 2023.05.11 |