콘텐츠로 이동

로그인 통합과 ERP/포탈 권한 분리 (세션 유지)

한 번 로그인하면 모든 모듈을 자유롭게 오갈 수 있어야 한다 — 목표는 단순했습니다. 그런데 인증 상태를 어디에, 어떤 모양으로 저장할지를 처음에 못 박지 않자, 서로 다른 모양의 인증 저장소가 두 벌 생겼습니다. 둘 다 “로그인됨”이라 멀쩡해 보였지만, 한 영역에서 다른 영역으로 넘어가는 경계에서 그 미세한 어긋남이 로그인 튕김 버그로 돌아왔습니다. 토큰은 멀쩡한데 로그인 화면으로 튕긴 것입니다.

SL.AIMS 통합 로그인 화면 — 좌측 브랜드 패널과 11개 모듈 안내, 우측 이메일/사번 로그인 폼과 데모 계정 버튼
실제 SL.AIMS 통합 로그인 화면. 여기서 한 번 로그인하면 전자결재·인사·출퇴근·회계 등 모든 모듈을 다시 묻지 않고 오갑니다 — 그 "한 번"을 떠받치는 게 이 글이 다루는 저장 규약입니다. (데모 계정의 직원 실명은 가렸습니다.)

용어부터 — SSO와 두 종류의 토큰

섹션 제목: “용어부터 — SSO와 두 종류의 토큰”

한 번 로그인, 끝까지 유지 — 의도된 트레이드오프

섹션 제목: “한 번 로그인, 끝까지 유지 — 의도된 트레이드오프”

사내 업무 앱의 UX 목표는 분명했습니다. 출근해서 한 번 로그인하면, 하루 종일 다시 묻지 않고 쓰게 하자. 그래서 인증을 짧은 수명의 access 토큰과 매우 긴 수명의 refresh 토큰으로 나눴습니다. refresh는 사실상 로그아웃 전까지 유지하고, access는 짧게 둬서 로그아웃의 즉시성을 보완합니다 — 로그아웃하면 곧 만료될 짧은 access 덕분에, 긴 refresh를 쓰면서도 “로그아웃은 빨리 먹히게” 만든 것입니다.

이건 보안과 내부 UX 사이의 의도된 절충입니다. 긴 refresh는 편하지만 노출 창이 커지고, 짧은 access는 안전하지만 자주 갱신해야 합니다. 둘의 균형점을 “내부 직원용 업무 앱”이라는 맥락에 맞춰 잡은 것입니다.

진짜 함정 — 인증 상태가 두 모양으로 갈라졌다

섹션 제목: “진짜 함정 — 인증 상태가 두 모양으로 갈라졌다”

진짜 함정은 토큰 수명이 아니라 인증 상태를 담는 그릇이었습니다. 포탈 영역과 전자결재 영역이 각자 편한 방식으로 인증 정보를 브라우저에 저장했습니다. 한쪽은 평평한 모양으로, 다른 한쪽은 상태 관리 라이브러리가 한 겹 감싼 모양으로 — 같은 사용자 정보인데 저장 키도 다르고 구조도 달랐습니다.

같은 사용자, 다른 그릇 모양 포탈 영역 저장소 모양 A — 평평한 구조 키도 다름 · 구조도 다름 전자결재 영역 저장소 모양 B — 한 겹 감싼 구조 키도 다름 · 구조도 다름 영역 경계 경계를 넘으면 상대의 그릇을 못 읽음 → 멀쩡한 토큰인데 로그인으로 튕김
두 영역이 서로 다른 키·구조로 인증 상태를 저장하면, 토큰이 멀쩡해도 경계를 넘는 순간 상대의 그릇을 못 알아봅니다. "인증 안 됨"으로 오해해 로그인 화면으로 튕깁니다. 토큰 만료가 아니라 **그릇 모양 불일치**가 원인입니다.

겉보기엔 둘 다 “로그인됨”이라 문제없어 보였습니다. 그런데 두 영역을 오갈 때, 한쪽이 다른 쪽의 그릇을 못 알아보는 경계가 있었습니다. 그 경계를 넘으면 토큰이 멀쩡한데도 로그인 화면으로 튕겼습니다. 실제로 이 튕김 현상을 근본 해소한 수정이 2026년 6월 12일에 있었는데, 원인은 토큰 만료가 아니라 두 저장소의 키·모양 불일치였습니다.

”로그인 통합”에 대한 통념실제로 중요한 것
토큰만 공유하면 된다토큰을 담는 그릇(키·구조)을 통일해야 한다
둘 다 “로그인됨”이면 OK영역 경계에서 서로의 그릇을 읽을 수 있어야 OK
튕기면 토큰이 만료된 것토큰은 멀쩡하고 그릇 모양이 안 맞을 수 있다
저장소는 영역마다 편한 대로”누가 정본인가”를 하나로 정해야 한다

이 종류의 버그가 특히 까다로운 건, 대부분의 경로에서는 멀쩡하기 때문입니다. 한 영역 안에서만 움직이면 자기 그릇만 읽으니 아무 문제가 없습니다. 어긋남은 오직 “한 영역 → 다른 영역”이라는 특정 경계를 건널 때만 드러납니다. 그래서 일반적인 로그인 테스트는 통과하고, 실제로 두 영역을 오가는 사용 흐름에서만 재현됩니다.

사용 흐름결과
포탈 안에서만 이동정상자기 그릇만 읽음
전자결재 안에서만 이동정상자기 그릇만 읽음
포탈 → 전자결재 경계 통과로그인으로 튕김상대 그릇 모양을 못 읽어 “인증 안 됨”으로 오해

이런 버그는 “토큰 만료겠지”라는 잘못된 가설로 시간을 잡아먹기 쉽습니다. 토큰 수명을 늘려 봐도 안 고쳐지는데, 그건 애초에 만료 문제가 아니기 때문입니다. 진짜 원인(그릇 모양 불일치)에 도달하려면, “토큰은 멀쩡한가?”를 먼저 확인하는 규율이 필요했습니다.

바로잡기 — 단일 권위 + 관용적 읽기

섹션 제목: “바로잡기 — 단일 권위 + 관용적 읽기”

해법은 두 가지였습니다.

  1. 단일 권위를 정한다. 인증 상태의 정본을 어느 한쪽으로 정하고, 다른 쪽은 그 정본에서 파생된 캐시로 취급합니다. “둘 다 정본”이면 둘이 어긋날 수 있지만, “하나는 정본, 하나는 캐시”면 어긋날 자리 자체가 없어집니다.
  2. 읽는 쪽을 너그럽게 만든다. 인증 상태를 읽는 코드가 두 모양을 모두 해석할 수 있게 합니다. 어느 그릇으로 들어와도 같은 사용자 정보를 꺼낼 수 있으면, 경계에서 오해가 생기지 않습니다.

되돌아보면, 로그인 통합을 설계할 때 가장 먼저 정했어야 할 건 토큰 수명이 아니라 인증 상태의 저장 규약이었습니다. 키 이름, 데이터 구조, 그리고 “어느 쪽이 정본이고 어느 쪽이 캐시인가”를 처음에 하나로 정해 뒀다면, 두 모양으로 갈라지지도 않았고 경계 튕김 버그도 없었을 것입니다. 영역이 둘 이상이면, 그 경계는 설계 단계에서 명시적으로 다뤄야 하는 1급 대상이지 나중에 발견할 사고 지점이 아닙니다.


이 글은 SL.AIMS를 만들며 겪은 현장 회고 중 하나입니다. 전체 그림은 〈사례연구: SL.AIMS〉에, 관련 글은 〈메뉴/기능 권한 설계를 초기에 안 한 것〉에 있습니다.