Node.js 상에서 로그인 세션을 관리하는 패키지인 Express-session을 사용하게 되면, 별도의 관리 로직을 구성하지 않아도 알아서 Request와 Response에 로그인 정보를 담아준다.

​

하지만 로그인에 따라 각 다른 페이지를 구성하거나, 노출 여부를 결정하는 경우라면 각 라우터의 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');
};
}

당연히 Rest API도 라우터로 처리하는데, 문제는 Ajax 콜을 보내는 경우 해당 요청이 로그인 상태가 아니라면 Ajax 요청에 대한 응답이 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);
}
});
}

위 코드는 단순 Ajax 호출을 편하게 하려고 만든 함수일 뿐이고, 주요 포인트는 beforeSend와 Success시 xhr.getResponseHeader함수이다.

​

물론 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 헤더를 추가하고 응답을 하는 코드가 추가된 것이다.

번호 제목 글쓴이 날짜 조회 수
56 Node.js로 ES6 코드 실행하기 (Babel) file 황제낙엽 2023.01.07 370
55 자바스크립트 CommonJS 모듈 내보내기/불러오기 (require) file 황제낙엽 2023.01.07 331
54 Node.js에서 ES 모듈(import/export) 사용하기 file 황제낙엽 2023.01.07 600
53 CommonJS 와 ES 의 Module 시스템 황제낙엽 2023.01.07 337
» [session] 기본 - Express-session 기반 로그인 세션 관리 황제낙엽 2022.01.03 308
51 [session] 기본 - 2 file 황제낙엽 2022.01.03 327
50 [session] 기본 - 1 황제낙엽 2022.01.03 326
49 [T아카데미] Node.js 프로그램 기초부터 응용까지 강좌 모음 황제낙엽 2021.03.15 235
48 Node.js 에서 Bulk INSERT 를 하는 방법 (multi insert) 황제낙엽 2021.02.02 1363
47 mysql, mysql2 모듈 버전 비교 황제낙엽 2021.01.31 595
46 [T아카데미/Node.js 프로그래밍] 프로그램 흐름 제어 (콜백지옥, Async, Promise) file 황제낙엽 2021.01.27 349
45 ORM 툴 Sequelize file 황제낙엽 2021.01.27 334
44 [connection과 pool-05] pool 생성이 너무 많은 경우의 database에서의 에러 - Too many connections file 황제낙엽 2021.01.27 483
43 [connection과 pool-04] connection pool 에서의 Transaction을 이용한 commit 과 rollback 황제낙엽 2021.01.27 341
42 [connection과 pool-03] mysql.createPool 과 connection.query 황제낙엽 2021.01.27 940
41 [connection과 pool-02] mysql.createPool 과 pool.query 황제낙엽 2021.01.27 460
40 [connection과 pool-01] mysql.createConnection 과 connection.query 황제낙엽 2021.01.27 388
39 [T아카데미/Node.js 프로그래밍/MySQL] createPool, getConnection 의 간단한 예제 (강의 예제) 황제낙엽 2021.01.27 379
38 여러 개의 데이터 베이스 연결을 동시에 관리하는 PoolCluster 황제낙엽 2021.01.16 2698
37 connetion pooling 과 connection leak 황제낙엽 2021.01.16 359