Node.js 상에서 로그인 세션을 관리하는 패키지인 Express-session을 사용하게 되면, 별도의 관리 로직을 구성하지 않아도 알아서 Request와 Response에 로그인 정보를 담아준다.
당연히 Rest API도 라우터로 처리하는데,
문제는 Ajax 콜을 보내는 경우 해당 요청이 로그인 상태가 아니라면 Ajax 요청에 대한 응답이 Login 페이지로 온다는 것이다.
위 코드는 단순 Ajax 호출을 편하게 하려고 만든 함수일 뿐이고, 주요 포인트는 beforeSend와 Success시 xhr.getResponseHeader함수이다.
하지만 로그인에 따라 각 다른 페이지를 구성하거나, 노출 여부를 결정하는 경우라면 각 라우터의 URL 매칭마다 이를 확인해주어야 한다.
매번 똑같은 함수를 계속해서 호출하거나, 복붙 할 수 없으므로 Middleware 형태의 인증 확인 절차를 거친다.
아래와 같은 코드를 많이 보았을 텐데, 실제 이와 같이 처리하게 되면 해당 라우터를 거치는 모든 요청들이 ensureLoggedIn 함수를 거쳐 로그인 여부가 판단되고, 로그인 페이지로 리다이렉트하거나 라우터로 가던길 계속 간다.
router.get('/', auth.ensureLoggedIn(), function(req, res, next){
return res.end();
});
//auth
function ensureLoggedIn(redirection) {
return function(req, res, next) {
if (req.isAuthenticated && req.isAuthenticated()) {
return next();
}
return res.redirect(redirection || '/auth/login');
};
}
이 문제를 해결하기 위해서는, Ajax 호출하기 전에 헤더에 이 요청이 Rest API 요청임을 뜻하는 값을 추가해주고
ensureLoggedIn 함수에서 해당 헤더를 발견하면, 리다이렉트가 아닌 특정 위치로 이동하라는 의미의 헤더를 추가하여 응답해주어야 한다.
따라서 클라이언트단과 서버단의 코드를 아래와 같이 고쳐야한다.
/*call ajax request*/
function sendAjax(url, data, callback, params){
$.ajax({
type: 'post',
url: url,
contentType : 'application/json; charset=UTF-8',
beforeSend : function(xhr){
xhr.setRequestHeader("calltype", "API");
},
timeout: 3000,
data: JSON.stringify(data),
async: true,
success: function (data, status, xhr){
if(xhr.getResponseHeader('redirect')){
window.location.href = xhr.getResponseHeader('redirect');
}
callback(null, data, params, status, xhr);
},
error : function (xhr, status, message){
callback(status, null, params);
}
});
}
물론 Complete함수도 있지만, Complete과 Success로 로직을 구분하여 실행하면 사용자 입장에서는 알림창과 동시에 성공에 대한 콜백도 실행되므로 Success 함수로 처리하는게 깔끔하다.
또한 beforeSend는 jQuery 로드 직후 글로벌하게 설정할 수 있으나, 나는 별로 그러고 싶지않아 sendAjax함수를 호출할 때마다 넣어주기로 했다. (취향차이임)
위의 서버단 ensureLoggedIn 함수를 아래와 같이 변경해야한다.
router.get('/', auth.ensureLoggedIn(), function(req, res, next){
return res.end();
});
// auth
function ensureLoggedIn(redirection) {
return function(req, res, next) {
if (req.isAuthenticated && req.isAuthenticated()) {
return next();
}
else{
if(req.headers.calltype && req.headers.calltype=='API'){
res.setHeader('redirect', redirection || '/auth/login');
return res.end();
}
return res.redirect(redirection || '/auth/login');
}
};
}
서버단에는 단순히 요청 헤더를 따서 API이라면, redirect 헤더를 추가하고 응답을 하는 코드가 추가된 것이다.
정말 쓸 내용없어서 그냥 이런거라도 포스팅 해야겠다. 끝
'프로그래밍 > 서버, DBMS' 카테고리의 다른 글
[티스토리] 티스토리 OPEN API 이용하여, Access token 발급받기 (2020.12.10 업데이트) (2) | 2019.03.10 |
---|---|
[서버] 웹 서비스 단일 로그인 (아이디당 1세션 유지) (0) | 2019.03.10 |
[Node.js] Node.js와 외부 프로그램(Java, C, C++) 연결 (bridge) (0) | 2019.03.04 |
[Node.js] Jade(pug) 템플릿 엔진 속도 문제 (1) | 2019.03.04 |
[웹 서버] Proxy 서버와 Forward, Reverse 프록시 (384) | 2019.03.04 |