이 프로젝트의 현재 구현은 Spring Boot + Thymeleaf 기반 데모다. 실제 서비스에서는 브라우저가 직접 CODEF API를 호출하지 않고, 클라이언트는 백엔드 API만 호출해야 한다.
클라이언트 개발자의 역할은 아래 두 가지다.
- 사용자의 건강검진 조회 입력과 간편인증 진행 상태를 UI로 안내한다.
- 백엔드가 제공하는 조회 시작 API와 상태 조회 API를 호출해 결과를 화면에 반영한다.
현재 서버 구현 기준 흐름은 아래와 같다.
sequenceDiagram
participant User as User
participant Client as Client UI
participant Backend as Backend API
participant CODEF as CODEF
User->>Client: 이름/휴대폰번호/생년월일/조회연도 입력
Client->>Backend: 조회 시작 요청
Backend->>CODEF: 1차 건강검진 조회 요청
CODEF-->>Backend: 성공 또는 추가인증 필요
Backend-->>Client: SUCCESS / PENDING / FAILED
alt PENDING
loop 인증 완료까지 반복
Client->>Backend: 상태 조회 요청
Backend->>CODEF: 2차 요청(is2Way=true)
CODEF-->>Backend: PENDING / SUCCESS / FAILED
Backend-->>Client: 현재 상태 반환
end
end
현재 서버 코드에서 사용하는 상태값은 SUCCESS, PENDING, FAILED, TIMEOUT 네 가지다.
사용자 입력 필드는 현재 HealthCheckForm.java 기준으로 아래와 같다.
| 필드 | 설명 | 검증 규칙 |
|---|---|---|
userName |
사용자 이름 | 필수 |
phoneNo |
휴대폰 번호 | 숫자 10~11자리 |
identity |
생년월일 | YYYYMMDD 8자리 |
searchStartYear |
조회 시작 연도 | 1900 이상 |
searchEndYear |
조회 종료 연도 | 1900 이상, 시작 연도 이상 |
authMethodKey |
간편인증 수단 키 | 필수, 현재 kakao 또는 pass |
telecomCode |
통신사 코드 | PASS 선택 시 필수, 0=SKT, 1=KT, 2=LG U+ |
클라이언트는 1차적으로 동일한 검증을 수행하되, 최종 검증은 반드시 백엔드에서 다시 수행해야 한다.
현재 데모의 수단 매핑은 아래와 같다.
authMethodKey="kakao"-> CODEFloginType=5,loginTypeLevel=1authMethodKey="pass"-> CODEFloginType=5,loginTypeLevel=5,telecom필수
현재 데모는 서버 세션과 서버 렌더링 화면에 의존한다. 실제 프로젝트에서는 아래처럼 REST API로 분리하는 것을 권장한다. 아래 계약은 실서비스 전환을 위한 권장안이며, 현재 데모에 동일한 REST 엔드포인트가 그대로 구현돼 있지는 않다.
POST /api/health-check/requests
요청 예시:
{
"userName": "홍길동",
"phoneNo": "01012345678",
"identity": "19900101",
"searchStartYear": 2023,
"searchEndYear": 2024,
"authMethodKey": "pass",
"telecomCode": "0"
}응답 예시:
{
"requestId": "4de0d5c0-b8fb-4a36-9cb4-4aa0f6db4d0f",
"status": "PENDING",
"message": "추가 인증이 필요합니다.",
"errorCode": "CF-03002",
"pollIntervalMs": 3000,
"summary": {
"pending": true
}
}GET /api/health-check/requests/{requestId}
응답 예시:
{
"requestId": "4de0d5c0-b8fb-4a36-9cb4-4aa0f6db4d0f",
"status": "SUCCESS",
"message": "조회가 완료되었습니다.",
"errorCode": "CF-00000",
"summary": {
"resultCode": "CF-00000",
"message": "성공",
"requestId": "4de0d5c0-b8fb-4a36-9cb4-4aa0f6db4d0f",
"status": "SUCCESS"
}
}실제 응답 필드명은 백엔드와 협의해 확정하면 되지만, 클라이언트 입장에서는 최소한 아래 값이 필요하다.
requestIdstatus—SUCCESS,PENDING,FAILED,TIMEOUT중 하나message— 사용자에게 표시할 안내 문구errorCode— CODEF 결과 코드 또는 내부 에러 코드summary— 결과 요약 객체pollIntervalMs— polling 주기 (밀리초)simpleAuthPending—true이면 자동 polling 대신 수동 확인 버튼 방식 사용 (5장 PENDING 참고)
참고: 현재 데모의 상태 조회 응답(
HealthCheckStatusResponse.java)에는pollIntervalMs와simpleAuthPending이 포함되어 있지 않다. 데모에서는 이 값을 HTML 템플릿 렌더링 시 주입하는 방식으로 처리하고 있으며, REST API 전환 시에는 JSON 응답에 포함해야 한다.
- 로딩을 중단한다.
- 조회 결과 화면으로 이동하거나 같은 화면에서 결과를 펼친다.
summary기준으로 결과 요약 UI를 구성한다.- 운영 환경에서는
rawResult전체를 사용자에게 그대로 노출하지 않는 편이 안전하다.
- "간편인증 진행 중" 상태를 보여준다.
- 안내 문구는 선택된 인증 앱 이름을 반영하되, "인증 앱에서 인증을 완료해 주세요" 수준으로 단순하게 유지한다.
- 사용자가 화면을 닫거나 취소하면 polling도 중단한다.
PASS도simpleAuth흐름이므로 자동 polling이 아니라 수동 확인 버튼 방식으로 처리한다.
PENDING 상태에서 polling 방식은 인증 방식에 따라 달라진다. 백엔드는 simpleAuthPending 플래그(또는 동등한 값)를 응답에 포함해야 하며, 클라이언트는 이 값에 따라 아래처럼 동작을 분기한다.
| 구분 | 일반 2Way (simpleAuthPending=false) |
simpleAuth (simpleAuthPending=true) |
|---|---|---|
| polling 방식 | pollIntervalMs 간격으로 자동 반복 |
사용자가 "결과 확인" 버튼을 클릭할 때만 요청 |
| 안내 문구 | "인증 앱에서 승인을 진행해 주세요" | "선택한 인증 앱에서 승인을 완료한 뒤 아래 버튼으로 결과를 확인하세요" |
| 이유 | 백그라운드에서 인증 상태가 자동 갱신됨 | 승인 완료 전 반복 요청 시 CODEF가 인증 실패(CF-12872)로 처리할 수 있음 |
simpleAuth 방식에서는 사용자가 인증 앱에서 승인을 완료한 뒤에만 결과를 확인하도록 유도해야 한다. 자동 polling을 적용하면 CODEF 측에서 반복 요청으로 인식해 인증이 실패할 수 있다.
- 오류 메시지와 재시도 버튼을 보여준다.
errorCode가 있으면 고객센터 대응용으로 별도 표시하거나 로그에 남긴다.
- 일정 시간 안에 간편인증이 완료되지 않았음을 표시한다.
- "다시 시도"를 기본 액션으로 둔다.
- CODEF 클라이언트 시크릿, 퍼블릭키, OAuth 토큰 요청 로직은 프론트엔드에 두면 안 된다.
- 주민등록 관련 값, 휴대폰 번호 같은 민감정보는 브라우저 로컬 스토리지에 저장하지 않는 편이 안전하다.
- polling은 화면 전환, 탭 종료, 취소 액션에서 반드시 해제해야 한다.
- 조회 시작 버튼은 중복 제출 방지를 위해 첫 요청 직후 비활성화하는 편이 좋다.
- 결과 화면은 "성공", "추가 인증 필요", "실패", "시간 초과" 네 상태를 명확히 구분해야 한다.
클라이언트가 errorCode로 받을 수 있는 주요 값은 아래와 같다. 상세한 목록은 백엔드와 협의해 확정한다.
| 코드 | 의미 | 클라이언트 대응 |
|---|---|---|
CF-00000 |
성공 | 결과 화면으로 전환 |
CF-03002 |
추가인증 필요 | PENDING 상태로 polling 시작 (정상 흐름) |
CF-12872 |
간편인증 반복 실패 | "인증에 실패했습니다. 처음부터 다시 시도해 주세요" 표시 |
CF-13002 |
인증 오류 | 오류 메시지 표시 + 재시도 안내 |
GATEWAY_ERROR |
백엔드-CODEF 통신 오류 | "일시적 오류" 메시지 + 재시도 안내 |
TIMEOUT |
인증 시간 초과 | "시간이 초과되었습니다" + 재시도 버튼 |
SESSION_MISSING |
세션 만료 | 처음부터 다시 시작 안내 |
- 세션 기반으로 갈지,
requestId기반 조회로 갈지 - polling 주기와 최대 대기 시간
- 결과 요약 포맷(
summary) 표준 - 오류 코드 표준화 방식
- 마스킹 규칙
- 조회 이력 저장 여부
- 인증 취소 API 제공 여부
- 입력 폼 검증과 에러 메시지 정의
- 중복 제출 방지
- polling 시작/중단 처리
simpleAuthPending여부에 따른 auto-poll / manual-poll 분기- 상태별 UI 분기
- 에러 코드별 사용자 메시지 매핑
- 실패/타임아웃 재시도 UX
- 민감정보 브라우저 저장 금지
- 네트워크 오류, 백엔드 오류, 인증 대기 상태를 각각 다른 메시지로 처리
현재 데모는 HealthCheckController.java 에서 HTML 화면 반환까지 모두 처리한다. 실제 서비스에서는 같은 흐름을 유지하더라도, 클라이언트는 HTML 대신 JSON API 계약을 기준으로 개발하는 것이 맞다.