6.6 KiB
6.6 KiB
EG-BIM Q&A 로그인부터 글 저장까지 전이맵
기준일: 2026-09-21
대상: qa-test.baroncs.co.kr / EG-BIM Q&A
구성: 목록(index.html) · 작성(write.html) · 상세(detail.html)
1. 전체 흐름
홈페이지 로그인 정보를 Q&A 사이트로 직접 전달하지 않는다. 홈페이지의 Q&A 링크는 별도 호스트로 이동하고, Q&A는 같은 BRSW OIDC SSO에 직접 인증을 요청한다. 이미 중앙 SSO 세션이 있으면 사용자는 로그인 화면을 보지 않고 Q&A 세션을 발급받는다.
flowchart TD
A[바론 홈페이지<br/>EG-BIM Q&A 링크] --> B[Q&A 목록 진입<br/>https://qa-test.baroncs.co.kr/egbim/]
B --> C{Q&A 세션 쿠키<br/>baron_qa_session 유효?}
C -- 예 --> G[정적 목록 페이지 표시]
C -- 아니오 --> D[302 /auth/login<br/>return_url 보관]
D --> E[Worker가 PKCE 생성<br/>state · verifier · nonce]
E --> F[BRSW OIDC SSO<br/>app.brsw.kr/oidc]
F --> F1{중앙 SSO 세션 존재?}
F1 -- 아니오 --> F2[SSO 로그인 화면]
F2 --> F3[최초 동의 화면<br/>필요 시 1회]
F1 -- 예 --> H[승인 코드 발급]
F3 --> H
H --> I[/auth/callback?code&state]
I --> J[Worker가 state 검증<br/>PKCE code_verifier 검증]
J --> K[Token Endpoint 호출<br/>Public Client · client_secret 없음]
K --> L[UserInfo 조회 및 claim 정규화]
L --> M[baron_qa_session 발급<br/>HttpOnly · Secure · SameSite=Lax]
M --> G
G --> N[문의 등록 버튼]
N --> O[작성 페이지<br/>write.html]
O --> P[GET /auth/session<br/>작성자·tenant 표시]
P --> Q{userUuid와 tenantId 존재?}
Q -- 아니오 --> R[제출 차단<br/>다시 로그인 안내]
Q -- 예 --> S[카테고리·제목·내용·비밀글 입력]
S --> T[등록 버튼 클릭]
T --> U[브라우저 UUID 생성<br/>feedbackId]
U --> V{첨부파일 존재?}
V -- 아니오 --> Y[첨부 메타데이터 빈 배열]
V -- 예 --> W[POST presign 요청]
W --> X[qa_cdn presigned URL로<br/>파일 PUT 업로드]
X --> Y[첨부파일 메타데이터 확정]
Y --> Z[feedback envelope 생성]
Z --> AA{apiBaseUrl 설정 여부}
AA -- 비어 있음<br/>현재 테스트 모드 --> AB[localStorage에 임시 저장]
AA -- 설정됨<br/>실서비스 모드 --> AC[POST /v1/qa/feedbacks<br/>feedback.hmac.kr API]
AB --> AD[등록 완료 toast<br/>상세 페이지 이동]
AC --> AE{API 성공?}
AE -- 예 --> AD
AE -- 아니오 --> AF[오류 표시<br/>재시도 가능]
2. 상태 전이표
| 상태 | 화면/주소 | 진입 조건 | 주요 처리 | 다음 상태 |
|---|---|---|---|---|
S0 |
홈페이지 | Q&A 메뉴 클릭 | 외부 Q&A URL로 이동 | S1 |
S1 |
/egbim/ |
Q&A 세션 유효 | R2의 목록 HTML 제공 | S5 |
S2 |
/auth/login |
세션 없음 | PKCE 상태 생성, SSO로 redirect | S3 |
S3 |
app.brsw.kr/oidc |
SSO 세션 없음 | 최초 로그인 및 동의 | S4 |
S4 |
/auth/callback |
code, state 수신 |
state/PKCE 검증, token/userinfo 조회 | S5 |
S5 |
목록 또는 작성 페이지 | baron_qa_session 유효 |
/auth/session에서 사용자 확인 |
S6 |
S6 |
write.html |
userUuid, tenantId 확인 |
작성 폼 입력 대기 | S7 |
S7 |
작성 페이지 | 등록 클릭 | feedbackId UUID 생성 및 입력 검증 |
S8 |
S8 |
작성 페이지 | 첨부 있음 | presign → qa_cdn 업로드 |
S9 |
S9 |
작성 페이지 | payload 준비 | feedback/support ticket envelope 생성 | S10 |
S10 |
API 또는 localStorage | apiBaseUrl 상태에 따라 분기 |
실제 DB 저장 또는 테스트 저장 | S11 |
S11 |
detail.html?id=... |
저장 성공 | 등록 완료 및 상세 이동 | 종료 |
3. 화면별 사용자 경험
A. 홈페이지
- EG-BIM 메뉴의 Q&A 링크만 제공한다.
- 로그인 정보, 쿠키, token,
SESSION_SECRET을 Q&A로 전달하지 않는다. - 링크 대상:
https://qa-test.baroncs.co.kr/egbim/
B. 중앙 SSO
- Q&A RP는
https://app.brsw.kr/oidc를 사용한다. - 최초 사용자는 SSO 로그인 및 동의 화면을 볼 수 있다.
- 같은 중앙 SSO 세션이 있으면 다음 접근부터 로그인 화면 없이 authorization code가 발급된다.
- Q&A RP는 PKCE Public Client이므로 client secret을 보내지 않는다.
C. Q&A 목록
- Worker가
baron_qa_session을 검사한다. - 세션이 없으면
/auth/login?return_url=...로 이동한다. - 세션이 있으면 R2의
egbim/index.html을 제공한다.
D. Q&A 작성
- 브라우저가
GET /auth/session을 호출한다. - 다음 작성자 정보를 화면과 payload에 사용한다.
userUuid
ssoSubject / requesterId
tenantId / requesterTenantId
tenantIds
scope
roles
email
name
department
phone
requesterId또는requesterTenantId가 없으면 제출을 차단한다.
E. 글 저장
- 브라우저에서
feedbackIdUUID를 1회 생성한다. - 같은 UUID를 다음 식별자로 재사용한다.
feedback.id
feedback.source_record_id
support_tickets.idempotency_key
- 첨부파일은
qa_cdn에 저장하고, DB에는 bucket/key 및 파일 메타데이터를 기록한다. - 실제 운영에서는 feedback API가 서버 측에서 Q&A 세션 또는 SSO token을 검증해야 한다.
4. 현재 테스트 모드와 운영 모드
현재 assets/config.js는 다음과 같이 apiBaseUrl이 비어 있다.
apiBaseUrl: ''
따라서 현재 등록 결과는 다음과 같이 동작한다.
글 작성 → UUID 생성 → localStorage 저장 → 상세 페이지 이동
운영 API 주소를 설정하면 다음 흐름으로 변경된다.
첨부 presign 요청
→ qa_cdn 직접 업로드
→ feedback.hmac.kr/v1/qa/feedbacks 호출
→ feedbacks/support_tickets 트랜잭션 저장
→ 상세 페이지 이동
5. 주요 실패 전이
| 실패 지점 | 사용자 화면 | 원인/확인 항목 |
|---|---|---|
| SSO 로그인 전 | 로그인 화면 | 중앙 SSO 세션 없음 또는 다른 SSO 환경 |
| callback | invalid_oauth_state |
OAuth cookie 만료, 호스트 변경, state 불일치 |
| token 교환 | oauth_token_exchange_failed |
issuer/endpoint/client ID/PKCE 설정 불일치 |
| 세션 확인 | authenticated:false |
baron_qa_session 없음·만료·SESSION_SECRET 불일치 |
| 작성자 확인 | UUID/tenant 오류 | SSO scope 또는 claim mapping 누락 |
| 첨부 업로드 | 업로드 실패 | presign API 또는 qa_cdn 권한 오류 |
| DB 저장 | API 요청 오류 | apiBaseUrl, CORS, API 인증, DB envelope 규격 오류 |