> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# 로그인 방법: 패스키, 코드, 소셜, SSO

> Didit에서 비밀번호, 이메일 코드, 매직 링크, 전화번호 코드, 패스키, 소셜, 조직 SSO, Didit ID Wallet 로그인을 설정하고 MFA와 비밀번호 재설정도 구성하세요.

> [!WARNING]
>
> 인증 기능은 새로 추가되었습니다. 호스팅 로그인 페이지에서 이 페이지의 모든 방식을 실행합니다. 아래 나열된 JSON endpoint는 자체 로그인 화면을 만드는 팀(`sign_in_ui: "own"`)을 위한 것입니다.

애플리케이션의 인증 관리 API에서 `PUT methods/{name}/` 호출과 `{"enabled": true}`를 사용하거나 콘솔에서 방식을 활성화합니다. 호스팅 로그인에는 활성화한 방식만 표시됩니다.

| 방식 | 이름 | 설정 |
| - | - | - |
| 비밀번호 | `password` | 비밀번호로 이메일 회원가입을 하려면 이 방식도 필요합니다. |
| 이메일 코드 | `code` | 없음. |
| 매직 링크 | `magic` | 없음. 호스팅 페이지에서만 사용할 수 있습니다. |
| 전화번호 코드 | `phone` | 전화번호 인증 워크플로의 `workflow_id`를 보냅니다. |
| 패스키 | `passkey` | 없음. |
| 소셜 로그인 | `google`, `microsoft`, `apple`, `github` | 자체 `client_id`와 `client_secret`. 샌드박스 애플리케이션은 대신 Didit의 테스트 앱을 사용할 수 있습니다(`credential_source: "didit_test"`). |
| 조직 SSO | `sso` | 고객 조직마다 SAML 또는 OIDC 연결이 필요합니다. |
| Didit ID Wallet | `wallet` | 항상 켜져 있습니다. 끌 수 없습니다. |

아래의 각 JSON 호출은 `POST authorize/`가 반환한 `transaction`으로 시작합니다. 이 트랜잭션은 10분 동안 유효합니다. 로그인에 성공하면 `{code, redirect_uri, state}`가 반환됩니다. 60초 안에 `POST token/`에서 코드를 교환하세요([token 및 JWKS](https://docs.didit.me/ko/authentication/tokens-and-jwks.md) 참조).

로그인 호출은 코드 대신 다음 단계 중 하나를 반환할 수 있습니다. 해당 단계를 완료하면 코드를 받게 됩니다.

| 응답 | 다음 단계 |
| - | - |
| `challenge`와 `factors`가 포함된 `mfa_required` | TOTP 또는 복구 코드를 보내거나 패스키를 사용하세요([MFA](#mfa) 참조). |
| `challenge`와 `uri`가 포함된 `mfa_enrollment_required` | MFA 정책에 인증 앱 등록이 필요합니다. `POST mfa/setup/`으로 등록하세요. |
| `challenge`와 `methods`가 포함된 `protection_required` | [봇 보호](https://docs.didit.me/ko/authentication/bot-protection.md) 정책이 추가 증명을 요구합니다. |
| `verification_url`이 포함된 `verification_required` | 인증 설정에서 회원가입 또는 로그인 시 라이브니스 또는 신분증 확인을 요구합니다. 사용자를 `verification_url`로 보내세요(30분 동안 유효). 승인된 확인이 끝나면 코드가 제공됩니다. |

## 비밀번호

`POST password/`는 `transaction`, `email`, `password`를 받습니다.

* 비밀번호는 `password_min_length`(8, 10, 12 또는 14자, 기본값 10자)를 충족해야 합니다. 흔히 쓰는 비밀번호와 숫자로만 된 비밀번호는 `password_policy`로 거부됩니다. [유출된 비밀번호 검사](https://docs.didit.me/ko/authentication/bot-protection.md#유출된-비밀번호)가 켜져 있으면 유출이 확인된 비밀번호는 `password_breached`로 거부됩니다.
* 이메일이 인증된 사용자만 비밀번호로 로그인할 수 있습니다.
* 잘못된 비밀번호, 존재하지 않는 이메일, 인증되지 않은 이메일, 잠긴 계정, 차단된 계정은 모두 같은 응답을 받습니다: `400 {"error": "invalid_credentials"}`. 사용자 인터페이스로는 어떤 경우인지 알 수 없으며, 공격자도 알 수 없습니다.

### 회원가입

회원가입에서는 먼저 이메일을 인증합니다. `purpose: "signup"`, `email`, `password`와 함께 `POST email/start/`를 호출한 다음, 코드와 함께 `POST email/complete/`를 호출하세요. 인증된 이메일로 계정이 생성됩니다.

* `signup_policy`는 누가 회원가입할 수 있는지 정합니다: `anyone`, `invited`(초대 링크가 있는 경우만), `allowed_domains`.
* `allow_subaddresses: false`(기본값)이면 로컬 부분에 `+`가 있는 주소는 거부됩니다.
* 브랜딩에 이용약관 또는 개인정보 처리방침 링크를 설정하면, 호스팅 회원가입 양식에서 사용자에게 이에 동의하도록 요청합니다.

## 이메일 코드

`POST email/start/`는 `transaction`, `purpose`(`login` 또는 `signup`), `email`을 받고 `202 {challenge, expires_in: 600}`를 반환합니다. 사용자는 10분 동안 유효한 6자리 코드를 받습니다.

`POST email/complete/`는 `transaction`, `purpose`, `challenge`, `code`를 받습니다. 시도는 5회 가능하며, 그 이후에는 사용자가 새 코드를 요청해야 합니다. 호스팅 페이지는 30초 후에 새 코드를 요청할 수 있게 합니다.

계정이 없는 주소로 로그인 코드를 요청할 때 `signup_policy`가 허용하면 계정이 만들어집니다. 이것이 비밀번호 없는 회원가입입니다.

## 매직 링크

호스팅 페이지는 15분 동안 유효한 로그인 링크를 보냅니다. 이 링크는 처음 시작된 PKCE 트랜잭션에 묶여 있으므로, 링크는 이를 시작한 흐름에서만 작동합니다. 사용자는 링크가 열린 페이지에서 로그인을 확인합니다. 매직 링크를 위한 JSON endpoint는 없습니다.

## 전화번호 코드

`POST phone/start/`는 `transaction`, `phone`, 선택 항목인 `channel`(`sms`가 기본값, 또는 `whatsapp`)을 받습니다. 번호는 E.164 형식으로 정규화됩니다. 응답은 `202 {challenge, expires_in: 600}`입니다.

`POST phone/complete/`는 `transaction`, `challenge`, 6자리 `code`를 받습니다. 시도는 5회 가능합니다.

* 전화번호 코드는 Didit의 전화번호 인증으로 전송됩니다. 전화번호 인증이 포함된 워크플로의 `workflow_id`로 이 방식을 활성화하세요.
* 처음 전화번호로 로그인하면 `signup_policy`가 `anyone`일 때만 계정이 생성됩니다.
* 전송에 실패하면 호출은 `503 {"error": "delivery_unavailable"}`을 반환합니다.

## 패스키

패스키는 WebAuthn을 사용합니다. 신뢰 당사자는 애플리케이션의 로그인 오리진입니다. Didit은 검색 가능한 자격 증명을 요청하며, 지문, 얼굴 또는 기기 PIN과 같은 사용자 검증을 항상 요구합니다. Didit은 증명을 요청하지 않습니다.

| 호출 | 본문 | 결과 |
| - | - | - |
| `POST passkeys/begin/` | `{transaction}` | `navigator.credentials.get()`에 사용할 `{challenge, options}`. 자격 증명 목록은 보내지 않으므로, 브라우저가 해당 오리진의 모든 패스키를 제시합니다. |
| `POST passkeys/complete/` | `{challenge, credential}` | 로그인 코드 또는 다음 단계. |
| `POST passkeys/register/` | 비어 있음, `Authorization: Bearer <access_token>` 헤더 포함 | `navigator.credentials.create()`에 사용할 옵션. |
| `POST passkeys/confirm/` | `{challenge, credential}`, 같은 token 포함 | 새 패스키의 `{id}`. |

* 패스키 챌린지는 5분 동안 유효합니다.
* 패스키를 추가하려면 최근 5분 안에 생성된 세션이 필요합니다. 그렇지 않으면 호출은 `403 {"error": "reauthentication_required"}`를 반환합니다. 먼저 사용자를 다시 로그인시키세요.
* 패스키 로그인은 다중 요소 인증으로 간주됩니다.
* 회원가입 후 호스팅 페이지는 패스키 추가를 제안합니다(`passkeys/setup/begin/` 및 `passkeys/setup/complete/`).
* 애플리케이션에 등록된 안드로이드 앱은 같은 패스키를 사용할 수 있습니다.

## 소셜 로그인

Google, Microsoft, Apple, GitHub 로그인은 고유의 OAuth 앱 자격 증명을 사용하며, 이는 `PUT methods/{provider}/` 및 `credentials: {client_id, client_secret}`로 설정됩니다. 제공자 콜백은 로그인 출처에 있습니다.

제공자로 처음 로그인할 때는 사용자가 코드로 이메일 주소의 소유권도 증명해야 합니다(`POST social/email/start/` 및 `POST social/email/verify/`). 이후 해당 제공자로 로그인할 때는 이 단계를 건너뜁니다.

GitHub은 최근 로그인을 증명할 수 없으므로, `prompt=login` 또는 `max_age`를 전송하면 제공되지 않습니다.

## 조직 SSO

조직 SSO를 사용하면 고객사 직원이 자사의 SAML 또는 OIDC ID 제공자를 통해 로그인할 수 있습니다. 고객 조직별로 `organizations/{id}/sso/`에서 `protocol`(`saml` 또는 `oidc`), `enabled`, `config`를 사용해 설정합니다.

* 고객사 IT 팀에 7일 동안 유효한 설정 링크를 보낼 수 있습니다.
* SAML 서비스 제공자 메타데이터는 `{origin}/sso/saml/metadata/`에 게시됩니다.
* 호스팅 로그인은 사용자의 인증된 이메일 도메인이나 로그인 URL의 `organization=<slug>`를 기준으로 연결을 찾습니다.

## Didit ID Wallet

이미 Didit에서 인증을 마친 사용자는 Didit ID Wallet으로 로그인할 수 있습니다. 이 방법은 항상 활성화되어 있습니다. 세션의 `verified_identity`에는 사용자가 공유하기로 선택한 정보가 담깁니다.

## MFA

두 번째 인증 요소는 인증 앱(TOTP)과 복구 코드, 또는 패스키입니다.

* `mfa_policy`는 MFA를 사용해야 하는 대상을 결정합니다: `optional`, `everyone`, `organization_admins`(기본값). 인증 앱을 등록한 사용자는 항상 이를 사용해야 합니다.
* 인증 앱을 등록하려면 새 세션(생성 후 5분 이내)으로 `POST mfa/enroll/`를 호출합니다. 응답은 `{challenge, uri}`이며, `uri`를 QR 코드로 표시합니다. 그다음 첫 번째 코드를 `POST mfa/confirm/`로 전송합니다. 응답에는 일회용 복구 코드 10개가 포함됩니다. 이 코드는 한 번만 표시합니다.
* 로그인 시 `challenge`와 함께 TOTP 또는 복구 코드를 `POST mfa/complete/`로 전송합니다. 시도 횟수는 5회입니다. 대신 패스키를 사용하려면 `POST mfa/passkey/begin/`과 `POST mfa/passkey/complete/`를 호출합니다.
* 코드는 30초 단위로 생성됩니다. 이미 승인된 코드는 다시 사용할 수 없습니다.
* SMS 및 이메일 코드는 두 번째 인증 요소로 사용할 수 없습니다.

## 비밀번호 찾기 및 재설정

`POST password-reset/start/`는 `email`을 받고 `202 {"status": "sent", "expires_in": 1800}`을 반환합니다. 해당 주소의 계정 존재 여부와 관계없이 응답은 동일합니다. 재설정 링크는 30분 동안 유효합니다.

`POST password-reset/complete/`는 `token`과 `password`를 받고 `{"status": "password_changed"}`를 반환합니다. 또한 다음 작업을 수행합니다:

* 잠금 상태를 해제합니다.
* `revoke_on_password_change`가 켜져 있으면(기본값) 모든 세션을 종료합니다.
* 해당 사용자의 다른 대기 중인 코드와 링크를 무효화합니다.

## 초대

`signup_policy: "invited"`이면 초대받은 사용자만 가입할 수 있습니다. 초대 링크는 7일 동안 유효하며, 호스팅된 `/invite` 페이지를 엽니다.

[token 및 JWKS](https://docs.didit.me/ko/authentication/tokens-and-jwks.md)로 계속하거나, 잠금 및 챌린지에 대해서는 [봇 보호](https://docs.didit.me/ko/authentication/bot-protection.md)를 읽어 보세요.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.