회사에서 운영하는 서비스 중 고객사(병원)에서 매일 회진을 시작하기 전 의사가 회진 일정을 선택 후 환자에게 알림 메시지를 전송하는 서비스가 있다. 고객사에서는 이 서비스를 의사들이 해당 서비스를 잘 사용하고 있는지 확인하기 위해 통계를 보여주는 서비스도 만들어 달라고 요청했었는데, 이번에 기능 추가 요구사항이 생겨 내가 업무를 담당하게 되었다. 단순히 통계 자료의 컬럼 몇 개를 추가해달라는 요구사항이라 쉬울 거라 예상했지만, 실제로 작업을 시작하면서 놀란 부분이 있다. 조회 조건에 따라 다르지만 가장 많이 조회하는 한 달 통계를 조회하면 API 응답 시간이 4.75초나 걸리고 있었다. 실제로 통계 자료를 자주 조회하는 것도 아니고 불편하다는 CS 도 없었지만 흔치 않은 성능 개선 기회라 놓칠 수 없었다..
최근 넥스트 스텝의 만들면서 배우는 Spring을 수강하고 있다.확실히 혼자 만들 때 보다 더 많은 것을 배운다고 느낀 게, 시작부터 톰캣을 냅다 구현해 버린다. 정확하겐 강의 자료로 구현해 주신 WAS를 이용해 클라이언트와 서블릿처럼 웹 요청/응답을 주고받는 기능을 구현한다. 요구사항으로 URL 별로 비지니스 로직이 담긴 서블릿을 호출하기도, 정적 리소스를 반환하기도 해야 했다. 해당 미션을 진행할 때 궁금한 점은 '기존 톰캣은 이용자가 구현한 서블릿과 정적 리소스 반환 중 어떤 것이 먼저 일어날까?'였다. 톰캣의 정적 리소스 반환톰캣의 우선순위를 파악하기 위해 간단한 실험을 진행했다.루트 경로의 서블릿을 등록 후, 존재하는 정적 리소스를 요청하면 어떻게 될까?루트 경로 서블릿이 존재할 때 정적 리소..
[Node.js/Express.js] Session, Interceptor 기능 개발 이전까지 세션과 인터셉터를 모두 개발 완료했다. 이제 매 요청 전 세션만 체크해주면 된다. 일단 해당 기능 적용 전 이전 글에서 Request 객체에 세션과 관련된 함수를 추가해주는 기능을 인터셉터로 변경해줬다. SessionManagerInterceptor class SessionManagerInterceptor extends HandlerInterceptor { /** * @type {SessionFactory} */ #sessionFactory; /** * @param {SessionStore} store */ constructor(store) { super(); this.#sessionFactory = new S..
[Node.js/Express.js] Session, Interceptor 기능 개발 지난 포스팅까지 세션 기능 개발을 완성했다. 요청이 왔을때, 서비스 로직을 수행하기 전 세션을 체크해서 권한이 있는 이용자의 요청인지 체크를 해주면 된다. 일전에 개발한 기존 세션기능은 모든 핸들러 함수 시작부분에 세션 Map을 뒤져 세션이 존재하는지 체크하는 로직을 일일이 넣어줬었다. 이번에 그런 수고를 줄이고자 인터셉터를 개발하기로 했다. HandlerInterceptor class HandlerInterceptor { /** * @param {Request} req * @param {Response} res * @return {boolean} */ preHandle = (req, res) => { return tr..
[Node.js/Express.js] Session, Interceptor 기능 개발 지난번 개발한 세션의 구조적인 변경을 진행했다. 이유는 현재 사내 프레임워크는 config.js라는 object에 필요한 정보들(DB host, port 등 과 같은 정보들)을 필드로 가지게 하고, 필요한 곳에서 모듈로 가져와 참조하는 방식을 사용했다. 그 중 Redis client와 관련된 정보도 있었다. 문제는 여기서 발생한다. 나는 config.js에 어떤 세션 스토어를 사용할지 명시할 계획이었으므로 개발자가 레디스 스토어를 사용하게 된다면 config.js에 const config = { redis: { socket: { host: 127.0.0.1, port: 6379 } }, sessionStore: Redi..
[Node.js/Express.js] Session, Interceptor 기능 개발 Redis로 세션을 저장하는 기능을 구현했지만, 흐름상 쿠키에 세션 key를 담아줄 경우 프록시서 버에서 쿠키를 탈취해 해당 key로 요청을 날리는건 마찬가지라는 생각을 했다. 요즘 JWT 같은 방법으로 인증관리를 구현한다고 알고있지만 아직 내가 잘 알지 못하고, 회사 분위기도 해오던 방법을 거스르는것에 반감이 있다보니 세션을 유지하고자 했다. JWT에 대해 알아볼때 봤던것이 쿠키에 httpOnly옵션을 줘서 클라이언트에서만 쿠키에 접근할 수 있도록 한다는 것을 참고해서 내가 구현한 세션/쿠키 방식에도 httpOnly 옵션을 추가하기로 했다. 쿠키 옵션 추가 기존 RedisSessionStore - geSession()..
[Node.js/Express.js] Session, Interceptor 기능 개발 입사 하자마자 진행했던 프로젝트인 paperless 회진 앱의 보안 점검 결과로 여러 문제점을 지적 당했다. 크게 앱 단계의 문제와 서버 단계의 문제로 나눌 수 있었는데, 서버쪽에 세션 미적용 SQL Injection 문제가 있었다. 이중 세션은 사실 JS의 Map변수를 이용해 로그인 하는 시점에 생성, setTimeout()을 통해 30분 후 해당 세션 삭제와 매 요청시 setTimeout()의 key값으로 clearTimeout()을 호출하고, 다시 30분 시작을 하도록 구현했었다. 테스트시에는 문제가 없었지만, 실제 서버에 올려보니 30분이 되지 않았는데 세션이 삭제되는 등 많은 문제가 있었다. 개발 당시에는 내가..