# 신규앱과 Baron SSO 연동 쉬운 설명

작성일: 2026-07-08
상태: 초안 v1

목적: 신규앱과 Baron SSO의 관계, 데이터 연동 방식, Hosted Login + PKCE 로그인, 모바일 배포 형태를 다른 팀원도 쉽게 이해할 수 있게 설명한다.

관련 근거:

- `docs/00_contract_tdc114plus_api_2026-07-02.md`
- `docs/00_policy_tdc114plus_screen_feature_2026-07-07.md`
- `docs/scenario_staging_baron_sso_login_verification_2026-07-06.md`
- `docs/policy_android_app_install_execution_2026-07-06.md`
- `app/lib/src/features/auth/data/auth_api_client.dart`
- `app/lib/src/features/auth/domain/auth_models.dart`
- `app/lib/src/features/auth/data/auth_repository.dart`

## 1. 한 줄 요약

`tdc114plus` 신규앱은 Baron SSO 자체가 아니라, Baron SSO를 로그인/사용자정보/조직정보 제공자로 사용하는 별도의 모바일 앱이다.

쉽게 말하면:

- 신규앱 = 사용자가 설치해서 실행하는 앱
- Baron SSO = 로그인과 사용자/조직 데이터를 제공하는 서버
- 두 시스템은 API로 데이터를 주고받는다

## 2. 신규앱과 Baron SSO의 관계

### 2.1 무엇이 누구인가

- 신규앱은 Flutter로 만든 Android/iOS 공통 모바일 앱이다.
- Baron SSO는 사용자 인증과 조직/직원 데이터를 관리하는 서버 쪽 시스템이다.
- 신규앱은 Baron SSO에 등록되는 별도 `RP(Relying Party)`로 본다.

여기서 `RP`는 쉽게 말하면:

- "SSO를 믿고 로그인 기능을 맡기는 서비스"
- 즉, 로그인 자체를 새로 만들지 않고 Baron SSO를 통해 인증받는 앱

그래서 신규앱은 Baron SSO의 일부 화면이 아니라, Baron SSO를 사용하는 별도 서비스라고 이해하면 된다.

## 3. 설치되는 앱 실행파일은 무엇인가

### 3.1 Android

Android에서 실제 기기에 설치되는 파일은 보통 아래 둘 중 하나다.

- `APK`
- `AAB`에서 스토어가 기기별로 풀어 배포한 설치 패키지

개발/테스트 단계에서는 보통:

- `flutter run`
- debug `APK`

를 사용한다.

운영 배포 관점에서는 보통:

- 사내 직접 배포면 `APK`
- Play Store 배포면 `AAB`

형태를 생각하면 된다.

현재 저장소 문맥상 Android 테스트에서는 debug APK를 직접 깔 수도 있지만, 기능 검증은 `flutter run` 중심으로 하도록 정책이 잡혀 있다. 이유는 이 앱이 실행 시점에 `TDC114_API_BASE` 같은 환경값을 함께 받아야 하기 때문이다.

### 3.2 iOS

iOS에서 실제 설치/배포에 쓰이는 것은 보통:

- 개발기기 설치용 app bundle
- TestFlight/App Store 배포용 `IPA`

라고 보면 된다.

즉 정리하면:

- Android는 주로 `APK` 또는 스토어용 `AAB`
- iOS는 주로 `IPA` 또는 TestFlight/App Store 배포

다.

## 4. 앱 실행파일 자체가 RP인가

이 질문은 자주 헷갈릴 수 있는데, 가장 쉬운 답은 아래와 같다.

- "앱 실행파일 그 자체"를 좁게 보면 그냥 설치 패키지다.
- 하지만 "그 앱 서비스 전체"를 넓게 보면 Baron SSO 입장에서는 하나의 `RP`다.

즉:

- `APK`, `IPA`는 설치물이다.
- 그 설치물을 통해 동작하는 `tdc114plus` 앱 서비스가 Baron SSO에 연동되는 `RP`다.

따라서 팀 내 설명에서는 아래처럼 말하면 가장 덜 헷갈린다.

`tdc114plus` 모바일 앱은 Baron SSO에 등록된 별도 RP이며, 사용자는 Android/iOS 기기에 그 RP의 클라이언트 앱을 설치해 사용한다.

## 5. 앱이 설치된 뒤 실제로 어떻게 동작하는가

네, 큰 흐름은 아래 이해가 맞다.

1. 사용자가 각 모바일 디바이스에 신규앱을 설치한다.
2. 사용자가 앱을 실행한다.
3. 앱은 Baron SSO authorization endpoint를 브라우저/커스텀탭으로 연다.
4. Baron SSO Hosted Login 화면에서 휴대폰번호 입력과 문자/메일 링크 인증을 처리한다.
5. 인증 완료 후 Baron SSO가 `https://114.hmac.kr/auth/callback`으로 authorization code를 돌려준다.
6. 앱은 PKCE `code_verifier`로 token을 교환하고 세션을 저장한다.
7. 앱은 그 세션으로 직원검색, 조직도, 사용자 표시 정보를 다시 조회한다.
8. 앱 화면은 Baron SSO가 준 로그인 결과와 조직/직원 데이터를 사용자에게 보여준다.

즉, "설치된 실행파일이 Baron SSO와 데이터를 주고받으면서 로그인과 표시 내용을 가져온다"는 이해는 맞다.

다만 더 정확히 말하면:

- 로그인 결과 일부는 앱 내부에 저장된다
- 이후 필요한 화면 데이터는 Baron SSO 연동 API를 다시 호출해서 가져온다

## 6. 어떤 데이터들을 주고받는가

## 6.1 로그인 시작 시 앱 -> Baron SSO

신규앱은 로그인 시작 시 headless API를 직접 호출하지 않는다.
앱은 PKCE 값을 만든 뒤 Baron SSO Hosted Login 화면을 연다.

```http
GET https://sso.hmac.kr/oidc/oauth2/auth
```

주요 query:

```text
client_id=tdc114plus-rp-client-id
redirect_uri=https://114.hmac.kr/auth/callback
response_type=code
scope=openid profile email tenants
state=random-state
nonce=random-nonce
code_challenge=S256-code-challenge
code_challenge_method=S256
```

의미:

- `client_id`: Baron SSO에 등록된 TDC114PLUS RP 식별자
- `redirect_uri`: 인증 후 앱으로 돌아오기 위한 App Link 주소
- `state`: callback 위조를 막기 위한 임시 검증값
- `code_challenge`: 앱이 가진 `code_verifier`를 해시한 PKCE 값

즉 앱은 "로그인 화면을 직접 만들지 않고", Baron SSO가 제공하는 로그인 화면으로 사용자를 보낸다.

## 6.2 Baron SSO Hosted Login 화면

휴대폰번호 입력, 문자/메일 링크 발송, 링크 승인 여부 확인은 Baron SSO 화면과 서버가 처리한다.

앱은 아래 정보를 직접 다루지 않는다.

- 휴대폰번호 인증 UI
- 승인 링크 생성
- `client_assertion`
- RP 개인키 또는 client secret
- headless `pendingRef` polling

이렇게 해야 공개 모바일 앱에 비밀키를 넣지 않는 PKCE 보안 모델과 맞다.

## 6.3 인증 완료 callback

인증이 끝나면 Baron SSO는 등록된 redirect URI로 이동한다.

```http
GET https://114.hmac.kr/auth/callback?code={authorization-code}&state={state}
```

앱은 Android App Link 또는 iOS Universal Link 설정을 통해 이 URL을 받아야 한다.

앱에서 확인할 것:

- callback의 `state`가 앱이 저장한 값과 같은지
- `code`가 존재하는지
- 오류 파라미터가 있으면 token 교환을 중단할지

## 6.4 token 교환

앱은 callback으로 받은 authorization code를 token endpoint에 보낸다.

```http
POST https://sso.hmac.kr/oidc/oauth2/token
```

요청 핵심:

```text
grant_type=authorization_code
client_id=tdc114plus-rp-client-id
code={authorization-code}
code_verifier={stored-code-verifier}
redirect_uri=https://114.hmac.kr/auth/callback
```

중요:

- PKCE 공개 앱이므로 client secret을 보내지 않는다.
- 앱이 처음 만든 `code_verifier`가 있어야 token 교환이 성공한다.
- token 교환 성공 후 앱은 access token, 만료시간, 사용자 기본 정보를 저장한다.

## 6.5 로그인 완료 후 앱 세션

token 교환이 성공하면 앱은 아래 정보를 세션으로 보관한다.

- access token
- 만료시간
- id token 또는 userinfo에서 얻은 사용자 기본 정보

이 사용자 정보는 아래처럼 쓰인다.

- `name`: 화면에 보여줄 사용자명
- `tenantName`, `tenantSlug`: 어느 회사/테넌트 소속인지
- `department`: 본인 부서
- `grade`, `position`, `jobTitle`: 직급/직위/직무

## 6.6 로그인 후 조회하는 업무 데이터

로그인 후에는 아래 같은 업무 데이터를 Baron SSO 연동 API에서 조회한다.

- 직원 목록
- 조직/가족사 목록
- 조직도
- 직원 상세 정보

현재 기준 원본 조회 API 메모:

- `GET /api/v1/integrations/org-context`
- `GET /api/v1/public/orgchart`

레거시 `/api/v1/tdc114plus/...` 데이터 경로는 과거 흔적으로만 보고 단계적으로 제거한다.

문서 기준 주요 데이터 API는 아래와 같다.

- `GET /api/v1/integrations/org-context`
- `GET /api/v1/public/orgchart`

즉 Baron SSO는 로그인만 해주는 것이 아니라, 앱이 필요한 직원/조직 데이터도 함께 제공하는 역할을 한다.

## 7. 데이터 형식은 무엇인가

기본 형식은 HTTP + JSON 이다.

조금 더 풀면:

- 통신 방식: 모바일 앱이 HTTPS API 호출
- 요청 본문 형식: JSON
- 응답 본문 형식: JSON
- 헤더: 보통 `Content-Type: application/json`, `Accept: application/json`

즉 이 앱은 웹페이지를 긁어오는 방식이 아니라, 구조화된 JSON API를 호출해서 데이터를 받는다.

## 8. 세션은 앱 안에 어떻게 저장되는가

코드상 현재 앱은 로그인 성공 시 아래 정보를 저장한다.

- `token`
- `expiresAt`
- `user`

저장 위치는 앱 내부 저장소(`SharedPreferences`)다.

그래서 앱을 다시 켰을 때:

- 저장된 세션이 아직 유효하면 로그인 화면을 건너뛴다
- 세션이 없거나 만료되면 다시 Baron SSO 로그인으로 보낸다

즉 앱은 매 화면마다 처음부터 새 로그인하는 것이 아니라, 받은 세션을 보관했다가 재사용한다.

## 9. 헤드리스 로그인(headless login)은 무엇이고, 왜 기본 방식이 아닌가

가장 쉬운 설명부터 하면:

헤드리스 로그인은 "앱 안에 Baron SSO의 로그인 웹화면을 직접 띄우지 않고, 앱이 API로 로그인 절차를 진행하는 방식"이다.

`headless`를 직역하면 "머리/화면이 없는" 느낌인데, 여기서는:

- 로그인용 별도 웹페이지 중심이 아니라
- 백그라운드 API 호출 중심으로 로그인 절차를 진행한다

는 뜻으로 이해하면 된다.

다만 현재 TDC114PLUS 기본 로그인 방식은 headless가 아니다.
현재 기준은 `Baron SSO Hosted Login + OIDC Authorization Code + PKCE`다.

이유는 간단하다.

- Flutter 모바일 앱은 공개 클라이언트라서 비밀키를 안전하게 숨길 수 없다.
- Baron Swagger의 headless API는 `client_assertion` 같은 confidential client 성격의 값을 요구한다.
- 앱이 headless API를 직접 호출하려면 APK 안에 비밀값 또는 개인키를 넣는 위험한 구조가 될 수 있다.
- Hosted Login + PKCE는 모바일 앱 표준 보안 모델과 더 잘 맞는다.

## 10. 이번 신규앱 로그인은 왜 특별한가

이번 신규앱 기본 로그인은 단순한 "전화번호 넣고 바로 로그인"이 아니다.

흐름은 아래와 같다.

1. 앱이 Baron SSO Hosted Login 화면을 브라우저/커스텀탭으로 연다.
2. 사용자가 Baron SSO 화면에서 휴대폰번호를 입력한다.
3. Baron SSO가 문자 또는 메일로 승인 링크를 발송한다.
4. 사용자가 그 링크를 열어 승인한다.
5. Baron SSO가 `https://114.hmac.kr/auth/callback`으로 authorization code를 돌려준다.
6. 앱이 PKCE 방식으로 token을 교환한다.
7. 앱이 세션 저장 후 첫 화면으로 진입한다.

즉 핵심은:

- 앱은 로그인 화면을 직접 구현하지 않는다.
- 휴대폰번호 입력과 링크 승인은 Baron SSO가 맡는다.
- 앱은 callback code를 받아 PKCE token 교환만 수행한다.

이다.

## 11. 왜 굳이 Hosted Login + PKCE로 하나

장점은 아래처럼 설명할 수 있다.

- 앱이 비밀번호, 휴대폰번호 인증 로직, 승인 링크를 직접 만지지 않는다.
- Baron SSO가 인증 UI와 인증 절차를 책임진다.
- 앱에는 client secret이나 개인키를 넣지 않아도 된다.
- Android/iOS 모두 표준 OIDC + PKCE 방식으로 확장하기 쉽다.
- 로그인 정책이 바뀌어도 Baron SSO Hosted Login 쪽을 중심으로 바꾸면 된다.

하지만 주의할 점도 있다.

- 앱 코드만 있다고 로그인 검증이 끝나지 않는다.
- Baron SSO RP 등록, redirect URI, App Link, PKCE token endpoint가 모두 맞아야 한다.
- staging/운영 환경에서 실제 테스트 번호와 링크 수신 경로가 맞아야 end-to-end 검증이 된다.

## 12. Hosted Login + PKCE와 headless 방식 차이

Hosted Login + PKCE:

1. 로그인 페이지로 이동
2. Baron SSO 화면에서 인증수단 입력
3. 문자/메일 링크 승인
4. App Link callback으로 앱 복귀
5. PKCE token 교환
6. 로그인 완료

headless 직접 호출:

1. 앱 화면에서 전화번호 입력
2. 앱이 API 호출
3. 사용자는 외부로 받은 링크를 열어 승인
4. 앱은 API로 상태를 확인
5. 완료되면 앱이 세션을 저장

현재 앱 기본 정책은 첫 번째, 즉 Hosted Login + PKCE다.
headless 직접 호출은 별도 신뢰 백엔드가 생기거나 Baron SSO가 모바일 공개 RP용 계약을 제공할 때만 재검토한다.

## 13. "전화번호만 넣으면 바로 로그인"과 같은가

아니다. 이번 기본 흐름은 그것과 다르다.

이번 기본 흐름은:

- Baron SSO 로그인 화면 진입
- 전화번호 입력
- 링크 발송
- 사용자 승인
- App Link callback
- PKCE token 교환 후 세션 발급

이다.

즉 전화번호 입력만으로 즉시 로그인시키는 구조가 아니라, 승인 단계를 끼운 비동기 로그인 구조다.

## 14. 팀원들이 가장 헷갈리지 않게 설명하는 표현

아래 표현을 권장한다.

`tdc114plus`는 Baron SSO에 등록된 별도 모바일 RP 앱이다. 사용자는 Android나 iPhone에 앱을 설치하고, 앱은 Baron SSO Hosted Login 화면을 브라우저/커스텀탭으로 열어 로그인한다. 전화번호 입력과 문자/메일 링크 승인은 Baron SSO 화면과 서버가 처리하며, 인증 완료 뒤 `https://114.hmac.kr/auth/callback` App Link로 앱에 돌아온다. 앱은 callback의 authorization code를 PKCE 방식으로 token 교환한 뒤 직원검색/조직도 같은 데이터를 Baron SSO 연동 API에서 조회해 화면에 표시한다.

## 15. 자주 나오는 질문에 대한 짧은 답

### Q1. 신규앱은 Baron SSO 안에 들어가는가

아니라기보다, Baron SSO를 사용하는 별도 앱이다.

### Q2. 앱 실행파일 자체가 RP인가

설치파일 자체보다는, 그 설치파일로 동작하는 앱 서비스 전체를 RP라고 보는 것이 더 정확하다.

### Q3. Android는 APK로 배포하는가

개발/사내 배포는 APK가 가능하고, 스토어 배포는 보통 AAB를 사용한다.

### Q4. iOS는 APK처럼 설치하는가

아니다. 보통 IPA 또는 TestFlight/App Store 방식이다.

### Q5. 앱이 설치된 뒤 Baron SSO와 계속 통신하는가

그렇다. 로그인할 때도 통신하고, 로그인 후 직원/조직 데이터를 가져올 때도 통신한다.

### Q6. 헤드리스 로그인은 화면이 아예 없다는 뜻인가

아니다. 사용자 화면은 있을 수 있다. 다만 현재 TDC114PLUS 기본 방식은 headless가 아니라 Baron SSO Hosted Login 화면을 브라우저/커스텀탭으로 여는 방식이다.

## 16. 결론

이번 신규앱은 단말에 설치되는 일반 모바일 앱이지만, 인증과 주요 사용자/조직 데이터는 Baron SSO와의 API 연동에 의존한다. 따라서 이 앱은 "독립 실행은 되지만 독립 인증은 하지 않는 RP 앱"이라고 이해하면 가장 정확하다.

또한 이번 로그인은 단순 즉시 로그인 방식이 아니라 `Hosted Login -> 문자/메일 링크 인증 -> App Link callback -> PKCE token 교환 -> 세션 저장` 흐름이다. 그래서 앱 실행파일만 설치되었다고 끝나는 것이 아니라, Baron SSO RP 설정, callback 도메인, App Link, token 교환이 함께 정상 동작해야 비로소 로그인과 첫 화면 진입이 완성된다.
