sitelink1 https://jcdgods.tistory.com/325 
sitelink2 https://blog.naver.com/apchima/221890637815 
sitelink3  
extra_vars4  
extra_vars5  
extra_vars6  

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 호출을 편하게 하려고 만든 함수일 뿐이고, 주요 포인트는 beforeSendSuccess시 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 3
55 자바스크립트 CommonJS 모듈 내보내기/불러오기 (require) file 황제낙엽 2023.01.07 1
54 Node.js에서 ES 모듈(import/export) 사용하기 file 황제낙엽 2023.01.07 1
53 CommonJS 와 ES 의 Module 시스템 황제낙엽 2023.01.07 1
» [session] 기본 - Express-session 기반 로그인 세션 관리 황제낙엽 2022.01.03 1
51 [session] 기본 - 2 file 황제낙엽 2022.01.03 0
50 [session] 기본 - 1 황제낙엽 2022.01.03 1
49 [T아카데미] Node.js 프로그램 기초부터 응용까지 강좌 모음 황제낙엽 2021.03.15 29
48 Node.js 에서 Bulk INSERT 를 하는 방법 (multi insert) 황제낙엽 2021.02.02 663
47 mysql, mysql2 모듈 버전 비교 황제낙엽 2021.01.31 269
46 [T아카데미/Node.js 프로그래밍] 프로그램 흐름 제어 (콜백지옥, Async, Promise) file 황제낙엽 2021.01.27 17
45 ORM 툴 Sequelize file 황제낙엽 2021.01.27 12
44 [connection과 pool-05] pool 생성이 너무 많은 경우의 database에서의 에러 - Too many connections file 황제낙엽 2021.01.27 50
43 [connection과 pool-04] connection pool 에서의 Transaction을 이용한 commit 과 rollback 황제낙엽 2021.01.27 64
42 [connection과 pool-03] mysql.createPool 과 connection.query 황제낙엽 2021.01.27 383
41 [connection과 pool-02] mysql.createPool 과 pool.query 황제낙엽 2021.01.27 23
40 [connection과 pool-01] mysql.createConnection 과 connection.query 황제낙엽 2021.01.27 39
39 [T아카데미/Node.js 프로그래밍/MySQL] createPool, getConnection 의 간단한 예제 (강의 예제) 황제낙엽 2021.01.27 49
38 여러 개의 데이터 베이스 연결을 동시에 관리하는 PoolCluster 황제낙엽 2021.01.16 2205
37 connetion pooling 과 connection leak 황제낙엽 2021.01.16 35