로그인 트랜잭션 생성
POST /fapi/v1/transactions · 환경의 로그인 호스트에서 호출
애플리케이션의 로그인 트랜잭션을 시작합니다. 호스팅된 로그인 페이지, UI 컴포넌트 및 헤드리스 클라이언트는 환경의 로그인 호스트(keenauth.app 하위 도메인 또는 검증된 사용자 지정 도메인)에서 이 엔드포인트를 호출합니다. 응답은 트랜잭션 쿠키 __Host-idp_ltx(Secure, HttpOnly, SameSite=Lax, 15분간 유효)를 설정하며, 이후 단계에서는 이 쿠키를 사용합니다.
요청
헤더:
| 헤더 | 필수 여부 | 설명 |
|---|---|---|
Idp-Client |
예 | SDK 식별자, <package>/<version> (<runtime>/<version>). |
Origin |
예 | 정확히 https://<sign-in host>이어야 합니다. |
본문:
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
client_id |
string | 예 | 애플리케이션의 클라이언트 ID입니다. |
redirect_uri |
string (URI) | 예 | 애플리케이션에 등록된 리디렉션 URI 중 하나입니다. |
응답
201 Created와 함께 트랜잭션 객체를 반환합니다.
{
"schema_version": 1,
"state": "identifier_pending",
"next_steps": [{ "step": "identifier", "fields": ["identifier"] }],
"csrf_token": "<token>",
"expires_at": "2026-10-05T10:15:00Z"
}
이 트랜잭션에서 상태를 변경하는 모든 요청에는 csrf_token을 Idp-Csrf-Token 헤더로 다시 전송하십시오.
인증 요청에서 SSO가 필요한 조직을 지정한 경우, 응답이 이미 federated_redirect(redirect_url 포함, 연결이 하나인 경우: 최상위 창을 해당 URL로 이동)이거나 sso_connections(여러 개인 경우: sso_start 단계에서 선택 항목을 전송)를 포함할 수 있습니다.
DPoP 바인딩 헤드리스 트랜잭션
자체 출처에서 실행되는 자사 SPA 또는 네이티브 앱은 DPoP 헤더(RFC 9449)를 사용하여 헤드리스 로그인을 시작합니다. 증명은 클라이언트가 보관하는 키(브라우저에서는 WebCrypto의 추출 불가능한 키, 기기에서는 플랫폼 키 저장소)로 서명하며, htm은 POST, htu는 https://<sign-in host>/fapi/v1/transactions입니다. 이때 트랜잭션은 쿠키 대신 해당 키에 바인딩됩니다. 쿠키는 설정되지 않으며 객체에는 csrf_token이 없습니다. 이후 트랜잭션의 모든 요청은 같은 키로 새로 생성한 증명을 보냅니다.
본문에 추가되는 필드는 인증 엔드포인트의 규칙에 따라 검사합니다.
| 필드 | 타입 | 필수 여부 | 설명 |
|---|---|---|---|
code_challenge |
string | 예 | PKCE S256 챌린지(RFC 7636). |
code_challenge_method |
string | 예 | S256. |
scope |
string | 아니요 | 공백으로 구분된 스코프, 예: openid profile email offline_access. |
state |
string | 아니요 | 인증 코드와 함께 반환됩니다. |
nonce |
string | 아니요 | ID 토큰의 nonce입니다. |
organization |
string | 아니요 | 조직 ID 또는 이름입니다. |
ui_locales |
string | 아니요 | 선호하는 언어입니다. |
resource |
string (URI) | 아니요 | 리소스 지시자(RFC 8707)입니다. |
Origin은 로그인 호스트 또는 애플리케이션에 허용된 웹 출처 중 하나일 수 있으며, 네이티브 앱은 아무 값도 보내지 않습니다. 이 방식은 자사 애플리케이션만 시작할 수 있습니다. 인증 엔드포인트가 거부한 필드는 422 validation_failed와 함께 OAuth 오류 코드를 errors[].code에 담아 반환합니다. 서버가 401 use_dpop_nonce를 응답하면 DPoP-Nonce 응답 헤더 값으로 새 증명에 서명하고 다시 시도하십시오. DPoP 헤더 없이 이 필드를 보내면 422 validation_failed(dpop_required)가 반환됩니다.
조직 전환
로그인한 사용자에 대한 프론트 API 액세스 토큰을 보유한 애플리케이션(참조: 프론트 API 액세스 토큰)은 화면 없이 사용자를 다른 조직으로 전환할 수 있습니다. 토큰은 Authorization: DPoP <token>으로 보내고, 토큰 키의 증명(ath 포함)을 함께 전송하십시오. 본문에는 flow를 organization_switch로 설정하고, 위의 DPoP 바인딩 헤드리스 필드(토큰 애플리케이션의 client_id, redirect_uri, code_challenge, state, nonce, scope)와 organization(GET /fapi/v1/me/organizations에서 얻은 org_… 형식의 조직 ID)을 포함합니다.
요청은 토큰의 세션으로 즉시 결정되며, 세션을 재사용하는 로그인과 같습니다. 조직의 정책(MFA, 유휴 시간 제한, SSO, IP 목록), 동의 및 대기 중인 법적 문서가 적용됩니다. 응답은 201이며, authorization_response를 포함한 completed 트랜잭션입니다. 그 안의 code를 code_verifier 및 같은 키의 증명과 함께 토큰 엔드포인트에서 교환하십시오. 새 토큰에는 org_id로 조직이 담깁니다. 열린 트랜잭션은 남지 않으며 쿠키도 설정되지 않습니다.
{
"schema_version": 1,
"state": "completed",
"next_steps": [],
"authorization_response": { "code": "<code>", "state": "<state>", "iss": "https://example.keenauth.app" },
"expires_at": "2026-10-05T10:15:00Z"
}
| 상태 | 코드 | 발생 조건 |
|---|---|---|
| 401 | unauthenticated |
토큰이 유효하지 않거나, 만료되었거나, 취소되었거나, 키에 바인딩되지 않았거나, 해당 애플리케이션이 활성 자사 애플리케이션이 아니거나, 세션이 종료된 경우입니다. |
| 422 | validation_failed |
flow가 organization_switch가 아니거나, client_id가 토큰의 애플리케이션이 아니거나, organization이 org_… ID가 아니거나, 이 애플리케이션에서 해당 조직으로 전환할 수 없는 경우(not_eligible)입니다. |
| 403 | authorization_failed |
조직이 전환 과정에서 표시할 수 없는 화면을 요구하는 경우입니다. error에는 OAuth 오류(login_required, interaction_required, consent_required)가 담깁니다. organization을 설정하여 새 로그인을 시작하십시오. |
토큰 없이 flow를 organization_switch로 보내면 422 validation_failed(access_token_required)가 반환됩니다.
오류
| 상태 | 코드 | 발생 조건 |
|---|---|---|
| 400 | malformed_request |
Idp-Client가 없거나 본문이 올바른 JSON이 아닌 경우입니다. |
| 403 | origin_not_allowed |
Origin이 로그인 호스트가 아닌 경우입니다. |
| 403 | headless_not_allowed |
타사 애플리케이션이 헤드리스 플로우를 시작하려고 한 경우입니다. |
| 404 | not_found |
해당 호스트가 어떤 환경의 로그인 호스트도 아닌 경우입니다. |
| 422 | validation_failed |
client_id가 이 환경의 애플리케이션이 아니거나, redirect_uri가 해당 애플리케이션에 등록되지 않았거나, 필드가 유효하지 않은 경우입니다. |
| 401 | invalid_dpop_proof |
DPoP 증명이 없거나, 유효하지 않거나, 재사용되었거나, 호스트가 DPoP 바인딩 트랜잭션을 제공하지 않는 경우입니다. |
| 401 | use_dpop_nonce |
DPoP-Nonce 응답 헤더 값으로 새 증명에 서명하십시오. |
| 503 | temporarily_unavailable |
의존 서비스를 사용할 수 없습니다. 나중에 다시 시도하십시오. |
예제
curl -X POST https://example.keenauth.app/fapi/v1/transactions \
-H "Idp-Client: my-app/1.0.0 (node/22.0.0)" \
-H "Origin: https://example.keenauth.app" \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{"client_id":"<client_id>","redirect_uri":"https://app.example.com/callback"}'
개인정보
이 엔드포인트는 개인정보를 처리합니다: 최종 사용자 프로필. KeenAuth API의 개인정보에서 저장되는 항목, 보관 기간 및 삭제 방법을 확인하실 수 있습니다. 어떤 필드에도 특수 범주의 개인정보(건강, 생체 정보, 종교, 정치적 견해, 성적 지향)를 보내지 마십시오.