하나의 계정으로 모든 서비스를 — SSO 로그인 가이드
GRAXEL의 SSO 시스템으로 100개 이상의 서비스를 하나의 계정으로 이용하는 방법을 안내합니다.
GRAXEL SSO: 1인 개발자가 한 계정으로 모든 서비스를 연결한 생존기
안녕하세요, GRAXEL을 운영하고 있는 1인 개발자입니다. 2025년 말이었나요, 제가 혼자서 세 번째 SaaS 앱을 기획하고 있을 때였습니다. 문득 코드를 작성하다가 현타가 강하게 왔습니다. "내가 구글이나 네이버도 아닌데, 왜 서비스마다 회원가입 페이지와 로그인 로직을 새로 짜고 있지?"
그 당시 저는 MyHyetaek과 JobFit, 그리고 사내용으로 쓰는 작은 백오피스 툴까지 총 3개의 별도 프로젝트를 굴리고 있었습니다. 사용자는 하나인데 DB에는 유저 테이블이 3개로 쪼개져 있었고, 비밀번호를 변경하려면 3곳에 들어가서 각각 바꿔야 하는 기형적인 구조였죠. 사용자 경험은 둘째치고, 제 자신이 유지보수하다가 미쳐버릴 것 같았습니다. 그래서 결심했습니다. 중앙 집중식 통합 인증(SSO, Single Sign-On) 시스템을 직접 구축하기로요. 오늘은 GRAXEL 포털에서 한 번의 로그인으로 모든 서비스를 자유롭게 넘나드는 SSO 아키텍처 도입기를 공유합니다. 저희 팀이 어떻게 일하는지 궁금하시다면 GRAXEL 소개 페이지를 참고해주세요.
왜 자체 SSO를 구축했는가?
물론 시중에는 Auth0, Okta, Firebase Auth 같은 훌륭한 인증 서비스(BaaS)들이 넘쳐납니다. 하지만 1인 개발자에게 월간 활성 사용자(MAU) 기반으로 매달 청구되는 달러 결제는 엄청난 압박입니다. 게다가 저는 제 데이터베이스에 유저 정보를 온전히 보관하고, 서비스 간의 세밀한 권한 제어를 하고 싶었습니다. 결국 '바퀴를 다시 발명하지 말라'는 격언을 살짝 무시하고, Next.js 기반의 자체 SSO 인프라를 만들게 되었습니다.
구현 스택과 아키텍처: NextAuth v5 + 크로스 서비스 JWT
핵심 기술 스택은 NextAuth.js (Auth.js) v5입니다. 최신 Auth.js 공식 문서를 닳도록 읽으며 Edge 런타임에서도 돌아가는 가벼운 인증 서버를 구상했습니다. 문제는 '어떻게 로그인 상태를 공유할 것인가'였습니다.
저는 서브도메인을 적극 활용하는 방식을 택했습니다. 모든 GRAXEL 서비스는 *.graxel.ai라는 도메인 아래에 묶여 있습니다. 포털은 portal.graxel.ai, 혜택 서비스는 myhyetaek.graxel.ai 식이죠. 사용자가 포털에서 로그인을 성공하면, 서버는 HS256 알고리즘으로 서명된 크로스 서비스 전용 JWT를 생성합니다. 그리고 이 토큰을 x-saas-token이라는 이름의 쿠키에 담아 굽습니다. 이때 쿠키의 Domain 속성을 .graxel.ai로 설정하는 것이 핵심입니다. 이렇게 하면 서브도메인이 달라도 브라우저가 알아서 쿠키를 들고 다니기 때문입니다.
사용자 입장에서 경험하는 매끄러운 3단계 흐름
- 포털 로그인 진입: 사용자가 MyHyetaek에서 '로그인' 버튼을 누르면 즉시 GRAXEL 통합 포털 로그인 화면으로 리다이렉트됩니다.
- 중앙 집중식 인증: 포털에서 이메일/비밀번호나 소셜 로그인(OAuth)을 통해 신원을 증명합니다. 성공 시 마스터 세션과 크로스 도메인 쿠키가 발급됩니다.
- 자동 인가 및 서비스 복귀: 원래 있던 서비스로 돌아오면, 해당 서비스의 미들웨어(Middleware)가 쿠키를 검증하고 즉시 로그인된 상태로 페이지를 렌더링합니다.
이 흐름을 구현하고 처음으로 포털 로그인 후 3개의 서비스 탭을 새로고침했을 때, 일제히 로그인 상태로 변하는 걸 보며 소름이 돋았던 기억이 납니다. 개발 가이드가 필요하시다면 GRAXEL 가이드 섹션에서 더 자세한 튜토리얼을 확인하실 수 있습니다.
보안 고려사항과 마주친 벽들
쿠키를 서브도메인 간에 공유하다 보니 보안에 각별히 신경 써야 했습니다. 첫 번째는 CSRF(Cross-Site Request Forgery) 방지였습니다. Auth.js에서 기본 제공하는 CSRF 토큰 메커니즘을 강화하고, 모든 API 요청에 엄격한 Origin 검증을 추가했습니다.
두 번째는 토큰의 암호화 방식이었습니다. 처음에는 JWE(JSON Web Encryption)를 써서 페이로드를 완전히 숨기려고 했으나, 여러 서비스의 Edge 미들웨어에서 매번 복호화 연산을 수행하니 지연 시간(Latency)이 눈에 띄게 늘어났습니다. 타협안으로 민감한 정보(이메일, PII)는 제외하고 최소한의 User ID와 Role만 담은 JWT를 만들고, 짧은 만료 시간(15분)을 두어 탈취 위험을 최소화했습니다.
향후 계획: 비밀번호 없는 세상, 패스키(Passkey) 도입
SSO를 통해 '여러 번 로그인하는 귀찮음'은 해결했지만, 여전히 '비밀번호를 입력하는 귀찮음'은 남아있습니다. 올해 하반기에는 WebAuthn 기반의 패스키(Passkey)를 SSO 시스템에 통합할 계획입니다. 지문 인식이나 Face ID 한 번으로 5개 이상의 GRAXEL 생태계 서비스에 동시 로그인하는 날이 머지않았습니다. 1인 개발자의 인프라 구축기는 계속됩니다. 다음 포스팅에서 또 다른 아키텍처 고민으로 찾아오겠습니다!
공유하기
이어 읽으면 좋은 글
같은 주제와 태그를 기준으로 GRAXEL 운영 맥락을 더 깊게 볼 수 있는 글입니다.
내혜택으로 정부 혜택 한 번에 찾기 — 완전 가이드
AI 기반 정부 혜택 검색 서비스 '내혜택'의 주요 기능과 사용법을 안내합니다.
Excel2Insight 활용 가이드 — 엑셀 데이터를 AI로 분석하는 법
Excel2Insight를 사용하여 엑셀 파일을 업로드하고 AI 인사이트 리포트를 생성하는 방법을 안내합니다.
외국인을 위한 한국 정부 지원금 신청법 — F-비자별 가이드 요약
F-2, F-5, F-6 비자 보유자가 신청 가능한 한국 정부 지원금의 핵심을 1인 개발자 시각에서 정리하고 필수 서류 준비 팁을 공유합니다.