> ## 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.

# JavaScript 빠른 시작

> Didit 인증 애플리케이션을 PKCE 기반 호스팅 로그인에 연결하는 방법을 안내합니다. 콜백 검증, 세션 확인, 로그아웃을 포함합니다.

> [!WARNING]
>
> 인증 기능은 새로 추가되었습니다. 이 호스팅 흐름 예제는 인증이 켜져 있는 애플리케이션과 함께 사용하십시오. `@didit-protocol/auth` 패키지는 아직 배포되지 않았으며, 아래 패키지 API는 설치 가능한 빠른 시작이 아니라 미리보기입니다.

## 호스팅 로그인 구성

샌드박스 애플리케이션에 정확한 콜백 URL과 웹 오리진을 등록하십시오. [개요](https://docs.didit.me/ko/authentication/overview.md)에 설명된 대로 콘솔에서 로그인 오리진(`https://<slug>.sandbox.auth.didit.me`)을 복사합니다. 이 예제는 브라우저의 암호화 API를 사용하며 HTTPS가 필요합니다. 샌드박스에서는 localhost도 사용할 수 있습니다. 등록해야 할 항목은 [로컬 개발](https://docs.didit.me/ko/authentication/overview.md#로컬-개발)을 참고하십시오.

`state`와 PKCE 검증기는 애플리케이션이 관리합니다. 호스팅 로그인은 비밀번호, 이메일, 패스키, 전화번호, SSO 및 필수 MFA 화면을 담당합니다. 이 코드에는 API 키를 넣지 마십시오.

```javascript auth.js theme={null}
// Replace both values with your registered application configuration.
const AUTH_BASE = "https://YOUR_SLUG.sandbox.auth.didit.me/";
const REDIRECT_URI = "https://YOUR_APP_ORIGIN/auth/callback";
const PENDING = "didit.auth.pending";
let tokens = null;

function base64url(bytes) {
  return btoa(String.fromCharCode(...bytes))
    .replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}

export async function signIn() {
  const verifier = base64url(crypto.getRandomValues(new Uint8Array(32)));
  const state = base64url(crypto.getRandomValues(new Uint8Array(32)));
  const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
  sessionStorage.setItem(PENDING, JSON.stringify({ verifier, state, startedAt: Date.now() }));
  const url = new URL("sign-in", AUTH_BASE);
  url.search = new URLSearchParams({
    redirect_uri: REDIRECT_URI,
    state,
    code_challenge: base64url(new Uint8Array(digest)),
    code_challenge_method: "S256",
  }).toString();
  window.location.assign(url.href);
}

export async function handleCallback() {
  const query = new URLSearchParams(window.location.search);
  const saved = sessionStorage.getItem(PENDING);
  sessionStorage.removeItem(PENDING);
  history.replaceState(null, "", window.location.pathname);
  if (!saved) throw new Error("Start sign-in again.");
  const pending = JSON.parse(saved);
  if (query.get("state") !== pending.state || Date.now() - pending.startedAt > 600000) {
    throw new Error("Invalid or expired sign-in. Start again.");
  }
  if (query.has("error") || !query.get("code")) throw new Error("Sign-in was not completed.");
  const response = await fetch(new URL("token/", AUTH_BASE), {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      grant_type: "authorization_code",
      code: query.get("code"),
      code_verifier: pending.verifier,
      redirect_uri: REDIRECT_URI,
    }),
  });
  if (!response.ok) throw new Error("Code exchange failed. Start sign-in again.");
  tokens = await response.json();
  return getSession();
}

export async function getSession() {
  if (!tokens) return null;
  const response = await fetch(new URL("session/", AUTH_BASE), {
    headers: { Authorization: `Bearer ${tokens.access_token}` },
    cache: "no-store",
  });
  if (!response.ok) {
    tokens = null;
    throw new Error("Session check failed. Sign in again.");
  }
  return response.json();
}

export async function signOut() {
  const current = tokens;
  tokens = null;
  if (!current) return;
  const response = await fetch(new URL("session/", AUTH_BASE), {
    method: "DELETE",
    headers: { Authorization: `Bearer ${current.access_token}` },
  });
  if (response.status !== 204) throw new Error("Local state cleared; server logout failed.");
}
```

로그인 버튼에서 `signIn()`을 호출하십시오. 등록된 콜백 페이지에서는 `handleCallback()`을 한 번만 호출하고, 로딩 상태를 표시하며, 실패하면 오류를 보여 주십시오. 현재 사용자는 `getSession()`으로 가져오고, 로그아웃은 `signOut()`으로 처리합니다. 콜백은 요청을 보내기 전에 주소 표시줄에서 코드를 제거합니다.

이 최소 예제는 토큰을 메모리에 보관하며, 페이지를 새로 고치거나 액세스 토큰이 만료되면 다시 로그인하도록 합니다. 세션을 유지하려면 백엔드를 사용하고 보안 쿠키를 쓰거나, 직렬화된 [리프레시 토큰 교체](https://docs.didit.me/ko/authentication/tokens-and-jwks.md)를 구현하십시오. 리프레시 토큰을 URL이나 로그에 넣지 마십시오. 프런트엔드의 세션 확인은 화면 표시만 제어합니다. 백엔드는 보호된 모든 요청마다 호출자를 검증해야 합니다.

## 인증 SDK 출시 미리보기

계획된 `@didit-protocol/auth` 코어는 `createDiditAuth({publishableKey})`, `signIn()`, `handleRedirectCallback()`, `getSession()`, `getToken()`, `onAuthStateChange`, `signOut()`을 제공하며, 신원 정보에 `vendorData`가 포함됩니다. 자동 기기 신호와 `verifyToken()`을 제공하는 서버 진입점도 추가될 예정입니다.

퍼블리시 가능 키는 `pk_live_`(프로덕션 애플리케이션) 또는 `pk_test_`(샌드박스 애플리케이션)에 애플리케이션 오리진을 패딩 없는 base64url 인코딩으로 변환한 값을 붙인 형태입니다. SDK는 API 호출을 이 오리진으로 보냅니다. 공개 키는 비밀이 아니며, 애플리케이션을 식별하는 용도로만 쓰입니다.

### 미리보기의 스텝업 및 재인증

* `stepUp({ action, amount?, currency?, redirectUri? })`은 `action`에 추가 신원 확인이 필요한지 묻기 위해 애플리케이션의 `POST step-up/`을 호출합니다. `action`은 `payout`, `bank`, `contact` 중 하나이며, payout 작업에는 `amount`가 필요합니다. 스텝업 규칙 중 하나가 적용되면 Didit이 반환한 인증 페이지로 이동합니다.
* `handleStepUpCallback(url?)`은 사용자가 돌아오는 페이지에서 실행됩니다. `?step_up=<id>`를 읽고, 주소 표시줄에서 이를 제거한 뒤, `GET step-up/{id}/`로 결과를 조회합니다.
* `reauthenticate({ method? })`은 같은 사용자를 다시 로그인시킵니다. 호스팅 페이지(기본값인 `method: "redirect"`)에서 진행하거나, 애플리케이션의 Didit 로그인 도메인에서만 사용할 수 있는 패스키(`method: "passkey"`)로 진행합니다. 호스팅 페이지에서 진행한 경우에는 `handleRedirectCallback()`으로 마무리하십시오. 다른 사람이 완료하면 `step_up_user_mismatch`와 함께 거부되며, 기존 세션은 유지됩니다.

두 스텝업 방식 모두 `{ id, status, approved, rule, method }`로 결과를 반환합니다. `status`는 `not_required`, `pending`, `approved`, `review`, `declined`, `expired` 중 하나입니다. `redirectUri`의 기본값은 클라이언트의 리디렉션 주소이며, 애플리케이션에 등록된 리디렉션 주소 중 하나와 정확히 일치해야 합니다. 확인이 필요한 경우 Didit은 다른 주소를 거부합니다. 백엔드가 스텝업 결과에 따라 동작하기 전에, 브라우저가 보고한 결과는 변경될 수 있으므로 `GET step-up/{id}/`와 사용자의 액세스 토큰을 사용해 스텝업을 다시 조회하십시오.

헤드리스 로그인에서도 애플리케이션의 보호 규칙에 의해 플래그되면 `protection_required`가 반환될 수 있습니다. 이 경우 사용자는 Didit이 이메일로 보낸 코드(`protection.verify({ code })`)를 입력하거나 패스키(`protection.passkey()`)를 사용해 완료합니다. `methods`에는 사용자가 사용할 수 있는 두 방식이 나열됩니다.

추측한 버전을 설치하거나 추측한 콜백 옵션으로 작업하지 마십시오. 호스팅 예제를 교체하기 전에 배포된 패키지의 내보내기, 발급자 및 키 설정을 확인하십시오. 비밀번호, 이메일 코드, 매직 링크, 패스키, 전화번호, MFA, 소셜 로그인, 스텝업, 에이전트 메서드는 해당 릴리스가 지원하는 API에 따라 달라집니다.

## 다른 제품 추가

백엔드는 액세스 토큰을 검증([토큰 및 JWKS](https://docs.didit.me/ko/authentication/tokens-and-jwks.md) 참고)하고 `vendor_data` 값을 읽어야 합니다. [인증 세션 생성](https://docs.didit.me/ko/sessions-api/create-session.md) 또는 [거래 토큰 발급](https://docs.didit.me/ko/transaction-monitoring/sdk-transaction-submission.md) 시 이 값을 `vendor_data`로 사용하십시오. 로그인에 성공했다고 해서 어느 제품에서든 사용자가 승인되었다는 뜻은 아닙니다.

배포 전에, 활성화된 샌드박스 애플리케이션에서 회원가입, 기존 사용자 로그인, 취소, 일치하지 않는 state, 재사용된 코드, 비밀번호 찾기, MFA, 만료, 로그아웃을 모두 테스트하십시오.


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