Files
2026-07-07 16:58:48 +09:00

4.0 KiB

baron-sso 로그인 흐름

순서도

flowchart TD
  A["1. backend/main.go 실행"] --> B[".env 로드, Logger/DB/IDP 초기화"]
  B --> C["API 라우트 등록"]
  C --> D["/api/v1/auth/*, /api/v1/user/me 등"]

  E["2. userfront/main.dart 실행"] --> F["Flutter 앱 초기화"]
  F --> G["GoRouter 생성"]
  G --> H["/ko/connect 또는 /ko/signin 진입"]

  H --> I["LoginScreen 생성"]
  I --> J["phoneOnly 모드 여부 결정"]
  J --> K["사용자 입력"]
  K --> L{"로그인 타입"}

  L -->|비밀번호| M["_handlePasswordLogin"]
  L -->|전화번호 connect| N["_handlePhoneOnlyLogin"]

  M --> O["AuthProxyService.loginWithPassword"]
  N --> P["AuthProxyService.loginWithPhoneOnly"]

  O --> Q["POST /api/v1/auth/password/login"]
  P --> R["POST /api/v1/auth/phone-login"]

  Q --> S["backend AuthHandler.PasswordLogin"]
  R --> T["backend PhoneLogin"]

  S --> U["IDP 인증"]
  T --> U

  U --> V{"login_challenge 있음?"}
  V -->|예| W["Hydra/OIDC accept 처리"]
  V -->|아니오| X["sessionJwt/token 응답"]

  W --> Y["redirectTo + token 응답"]
  X --> Z["userfront 성공 처리"]
  Y --> Z

  Z --> AA["_onLoginSuccess"]
  AA --> AB["AuthTokenStore.setToken"]
  AB --> AC{"redirectTo 있음?"}
  AC -->|예| AD["webWindow.redirectTo"]
  AC -->|아니오| AE["profile load"]
  AE --> AF["dashboard 이동"]
sequenceDiagram
  participant Browser as Browser
  participant App as userfront (Flutter)
  participant Store as AuthTokenStore
  participant Proxy as AuthProxyService
  participant API as backend /api/v1/auth
  participant IDP as IDP/Hydra/Kratos

  Browser->>App: /ko/connect 또는 /ko/signin 진입
  App->>App: GoRouter가 LoginScreen 생성
  App->>Browser: 로그인 UI 렌더링

  Browser->>App: 로그인 정보 입력 후 제출
  alt 비밀번호 로그인
    App->>Proxy: loginWithPassword(loginId, password, loginChallenge?)
    Proxy->>API: POST /api/v1/auth/password/login
    API->>IDP: 자격 증명 검증
    IDP-->>API: 세션 토큰/쿠키
    API-->>Proxy: sessionJwt, token, provider, redirectTo?
  else connect 전화번호 로그인
    App->>Proxy: loginWithPhoneOnly(phoneNumber, loginChallenge?)
    Proxy->>API: POST /api/v1/auth/phone-login
    API->>IDP: 전화번호 기반 인증
    IDP-->>API: 세션 토큰/쿠키
    API-->>Proxy: sessionJwt, token, provider, redirectTo?
  end

  Proxy-->>App: JSON 응답
  App->>App: _onLoginSuccess(token, provider, redirectTo)
  App->>Store: setToken(token, provider)
  alt redirectTo 있음
    App->>Browser: redirectTo로 이동
  else OIDC challenge 있음
    App->>Proxy: acceptOidcLogin(login_challenge, token)
    Proxy->>API: POST /api/v1/auth/oidc/login/accept
    API->>IDP: login accept 처리
    IDP-->>API: OIDC redirect URL
    API-->>App: redirectTo + token
    App->>Store: setToken(...)
    App->>Browser: OIDC redirect
  else 일반 로그인
    App->>App: profile load
    App->>Browser: /{locale}/dashboard 이동
  end

흐름 요약

  1. backend/cmd/server/main.go가 먼저 실행되어 라우트를 엽니다.
  2. userfront/lib/main.dart가 실행되어 /ko/signin, /ko/connectLoginScreen으로 연결합니다.
  3. 사용자가 로그인하면 login_screen.dart_handlePasswordLogin() 또는 _handlePhoneOnlyLogin()이 실행됩니다.
  4. AuthProxyService가 백엔드 인증 API를 호출합니다.
  5. 백엔드가 성공 응답을 주면 AuthTokenStore에 토큰을 저장합니다.
  6. redirectTo가 있으면 그쪽으로 이동하고, 없으면 dashboard로 이동합니다.

참고 파일