최근 면접을 보았습니다. 안타깝게도(당연하게도) 떨어졌지만…
“JWT 토큰을 사용하셨던데, 추가적으로 보안과 관련해서 고려하신 사항이나, 설계를 하신 부분이 있나요 ?”
라는 질문에 어버버하며 access token 관련과 https 처리를 진행했다는 멍청한 대답을 하였습니다. 복기를 하면 할수록 떨어질만 했다 라는 생각이 드네요.
이 참에 확실히 정리를 해보자 싶었습니다.
프로젝트에서 진행했던 설계
JWT 토큰 기반 도메인 분리를 통해, 공장별로 분리되어 있던 작업현황 화면을 단일 페이지로 통합
- Problem
- 동일한 구조의 작업현황 조회 화면을 3개 공장에서 각각 사용해야 했으며, 공장별로 별도의 페이지를 만들경우 화면 및 로직 중복 증가
- 작업자가 본인 소속 공장의 데이터만 조회할 수 있도록 권한 기반 데이터 접근 제어 필요
- Solution
- 로그인 시 발급되는 JWT 토큰에 사용자 타입(user_type)과 공장 코드(plant_cd)를 포함하여 사용자 소속 도메인 명확화
- 작업 현황 조회 시 JWT토큰의 도메인을 기준으로 자동 필터링되도록 구현하여 공장별로 분리된 조회 화면의 단일 페이지 통합
- Result
- 화면 및 로직 중복 제거를 통한 유지보수 효율성 향상
- 권한 기반 데이터 조회를 통한 보안성 및 데이터 정합성 확보
포트폴리오에 작성한 내용 일부입니다.
설계 내용
해당 프로젝트에서는 기존에 1 ~ 3 공장의 작업현황 화면이 각각 분리되어 있었으며, 사용자는 본인이 속한 공장의 화면만 볼 수 있도록 설계되어 있었습니다.
가장 단순한 방법은 공장별로 동일한 구조의 작업현황 화면을 각각 구현하고, 메뉴 권한을 통해 접근을 제한하는 것이었지만, 이 경우 화면 및 로직의 중복이 발생하여 유지보수 비용이 증가하는 문제가 있었습니다.
이를 해결하기 위해 JWT Access Token에 공장 코드를 포함시키고, 작업 현황 조회 시 해당 공장코드를 기준으로 데이터를 필터링 하도록 설계하였습니다.
설계 시 고려했던 내용
1.인증 및 토큰 검증 구조 설계 - 토큰 위변조 감지, 토큰 만료 및 재발급 정책
해당 프로젝트는 작업현황 조회 뿐만 아니라, 로그인 이후 모든 API 요청에 대해 토큰 기반 인증이 필요했습니다. 이를 위해 공통 미들웨어를 구성하여, API 수행 전에 토큰 검증과정을 거치도록 설계하였습니다.
클라이언트 요청 시 Authorization Header에서 Access Token을 추출하고, jwt.verify를 통해 토큰의 서명 및 유효성을 검증하였습니다. 검증에 성공한 경우에는 decoded payload를 req.user에 저장하여, 이후 API 로직에서 사용자 정보를 활용할 수 있도록 구성하였습니다.
Access Token이 만료된 경우에는 Refresh Token을 통해 재검증을 수행하도록 하고, Refresh가 없는 경우에는 인증 실패로 처리하여 로그인 화면으로 이동되도록 처리하였습니다.
2.HTTPS 통신 및 Refresh Token 저장 방식
JWT는 payload가 암호화되지 않는 구조이기 때문에, 토큰이 네트워크 구간에서 탈취 될 위험이 존재합니다. 이 때문에 HTTPS 기반 설정이 필수적이고, Refresh Token 전송 및 저장 방식에 대한 고려가 필요합니다.
초기 개발단계에는 HTTPS 적용을 하지 않은 상태였기에 쿠키에 httpOnly 및 secure 옵션을 적용하지 않았습니다. 이후 운영 단계에서 HTTPS 적용이 된 이후 개발/운영 환경을 구분하여 운영 환경일 경우, httpOnly, secure 옵션이 적용된 쿠키로 관리하였습니다.
3.로그 저장을 통한 사용자 행위 추적
인증을 통해 접근을 제어하는 것 뿐만 아니라, 인증 이후 사용자가 어떤 기능을 수행했는지 추적할 수 있어야 한다고 생각했습니다. 이를 위해 API가 호출될 때 마다 로그를 저장하는 미들웨어를 구성하였습니다.
로그에는 USER_ID, PATH, HOST_NAME, PROGRAM_ACTION, PROGRAM_CONTROLLER, PROGRAM_FUNCTION, 등의 정보를 기록하도록 하였으며, 이를 통해 사용자별 요청 이력과 기능 수행 내역을 확인할 수 있도록 하였습니다. 로그를 통해 권한 오남용이나 비정상 접근 발생 시 추적이 가능하도록 설계하였습니다.
추가적으로 고려했어야 할 보안 요소
1.Rate Limiting
로그인 or 토큰 재발급 API에 대해 요청 횟수를 제한하는 Rate Limiting 전략이 필요합니다. 사용자가 상대적으로 적다보니 고려하지 않았지만, 탈취 등의 보안 이슈가 생길 경우 무차별 대입공격이나 토큰 재발급 시도를 줄이는 등의 인증 시스템 오남용을 방지할 수 있습니다.
2.Reverse Proxy 필터링
Reverse Proxy(Nginx)를 통해 클라이언트 요청을 백엔드로 전달할 때 Host, Client IP, 프로토콜 정보를 설정하여 백엔드에서 인증처리 할때 활용할 수 있도록 할 수 있습니다.
결론
프로젝트를 진행하면서 JWT에 대한 개념을 이해하고 적용했다고 생각했는데, 막상 면접 과정에서 해당 구조를 조리있게 설명하지 못한게 매우 아쉽습니다.
그래도 면접을 통해 단순히 기능을 구현하는 것 뿐만 아니라, 설계 의도를 명확하게 설명하는 것도 중요하다는 것을 깨달았습니다.
다음부턴 타인에게도 위처럼 설명할 수 있도록 충분히 공부하고 이해하는 방향으로 개발하고자 합니다.