---
url: 'https://www.corbado.com/ko/blog/passkeys-cheat-sheet'
title: '개발자를 위한 패스키 치트 시트'
description: 'WebAuthn 및 패스키 구현에 관한 개발자 가이드입니다. 치트 시트를 PDF로 다운로드하거나 이 웹사이트에서 모든 정보를 한곳에서 확인하세요.'
lang: 'ko'
author: 'Lukas R.'
date: '2026-07-03T07:12:48.228Z'
lastModified: '2026-07-03T07:12:54.784Z'
keywords: '패스키,치트 시트,WebAuthn,개발자 가이드,패스키 구현'
category: 'Passkeys Implementation'
---

# 개발자를 위한 패스키 치트 시트

## 무료 다운로드

전체 **패스키 치트 시트를 무료로 다운로드**하고 모든 인사이트를 얻어보세요.

- ✅ 누적 다운로드 4,000회 이상
- ✅ Ally, Kmart, Octopus [Energy](https://www.corbado.com/passkeys-for-energy) 및 Stanford CS 개발팀의 요청
- ✅ 마케팅 요소 없이 오직 기술적 인사이트만 제공

## Key Facts

- 패스키를 이용한 인증은 등록(증명)과 로그인(어서션)이라는 두 가지 **세레모니**를 사용하며, 각각은 서버에서 생성하고 인증기가 서명한 무작위 챌린지를 요구합니다.
- **PublicKeyCredentialCreationOptions**는 패스키 등록을 관리하고 **PublicKeyCredentialRequestOptions**는 로그인을 관리합니다. 두 객체 모두 서버 측에서 생성되며 인증기가 서명할 챌린지를 포함합니다.
- **Conditional UI**는 사용 가능한 패스키를 자동 완성 제안으로 표시하지만, 검색 가능한 자격 증명(상주 키)이 필요하며 모든 OS 및 브라우저 조합에서 지원되지는 않습니다.
- **신뢰 당사자 ID(rpID)**는 패스키를 도메인에 바인딩합니다. URL이 rpID와 일치하거나 rpID의 비공개 접미사 하위 도메인인 경우에만 인증이 성공합니다.
- 패스키는 키 생성에 **COSE 알고리즘**을 사용하며, 특정 알고리즘은 증명 객체의 parsedCredentialPublicKey 속성에 기록됩니다.

## 1. WebAuthn 세레모니

패스키를 이용한 인증은 **등록**(또는 **증명 단계**)과 **로그인**(또는 **어서션 단계**)이라는 두 가지 프로세스(세레모니)를 기반으로 합니다.\
각 단계는 서버에서 생성한 무작위 챌린지를 요구하며, 이 챌린지는 인증기에 의해 서명되고 사용자를 확인하기 위해 WebAuthn 서버로 다시 전송됩니다.

### 1.1 등록 (증명)

![Process flow of the registration ceremony in WebAuthn](https://www.corbado.com/website-assets/65fad0076e7b4367976ee993_cs_1_1_registration_flow_min_26eb12d652.png)_등록 세레모니는 PublicKeyCredentialCreationOptions와 증명이라는 두 가지 핵심 객체를 사용합니다._

[Watch on YouTube](https://www.youtube.com/watch?v=0hRYXHESA24)

### 1.2 로그인 (어서션)

![Process flow of the login ceremony in WebAuthn](https://www.corbado.com/website-assets/65fad0f2e412e9ad9d2a5bf1_cs_1_2_login_flow_min_2aaefc04dd.png)_로그인 세레모니는 PublicKeyCredentialRequestOptions와 어서션이라는 두 가지 핵심 객체를 사용합니다._

## 2. 주요 객체

패스키를 이용한 등록 및 로그인에는 다음 네 가지 주요 객체가 있습니다.

- PublicKeyCredentialCreationOptions
- PublicKeyCredentialRequestOptions
- attestation(증명)
- assertion(어서션)

이 섹션에서는 PublicKeyCredentialCreationOptions에서 사용되는 authenticatorSelection 객체에 대해서도 설명합니다.

### 2.1 Public Key Credential Creation Options

PublicKeyCredentialCreationOptions는 증명 단계(등록)의 핵심 객체입니다. [WebAuthn 서버](#webauthn-server)에서 생성되어 반환됩니다.

```json
{
    "PublicKeyCredentialCreationOptions": {
        "rp": {
            "id": "passkeys.eu",
            "name": "Corbado Passkeys Demo"
        },
        "user": {
            "displayName": "john.doe",
            "id": "dXNyLZ….DU10Tc",
            "name": "john@doe.com"
        },
        "challenge": "888fix4Bus...pHHr3Y",
        "pubKeyCredParams": [
            {
                "alg": -7,
                "type": "public-key"
            },
            {
                "alg": -257,
                "type": "public-key"
            }
        ],
        "excludeCredentials": [],
        "authenticatorSelection": {
            "authenticatorAttachment": "platform",
            "residentKey": "required",
            "userVerification": "required"
        },
        "attestation": "none",
        "extensions": {}
    }
}
```

이 객체는 다음 속성을 포함합니다.

- **rp:** 신뢰 당사자(사용자를 인증하려는 서버)를 식별합니다. 섹션 [4.2 신뢰 당사자 ID (rpID)](#relying-party-id)를 참조하세요.
- **user:** 증명을 요청하는 사용자 계정에 대한 데이터를 포함합니다. ID는 신뢰 당사자가 선택한 바이트 시퀀스이며 개인 정보를 포함해서는 안 됩니다. 사용자 이름이나 이메일 주소는 대신 name 또는 displayName 속성에 저장됩니다. 자세한 내용은 섹션 [4.1 데이터베이스 스키마](#database-schema)에서 확인하세요.
- **challenge:** 무작위로 생성된 base64URL 인코딩된 BufferSource로, 인증기에 의해 서명되어야 합니다.
- **pubKeyCredParams:** 생성될 자격 증명의 지정된 속성으로, 일반적으로 지원되는 알고리즘을 의미합니다.
- **timeout:** 클라이언트가 호출이 완료될 때까지 기다릴 선택적 시간(밀리초)입니다.
- **excludeCredentials:** 한 기기에서 여러 패스키 생성을 제한하기 위한 자격 증명의 선택적 목록입니다.
- **authenticatorSelection:** residentKey가 필요한지 여부 등 메소드에 사용될 인증기에 대한 선택적 선택 사항입니다. [2.5 authenticatorSelection](#authenticatorSelection)을 참조하세요.
- **attestation:** 증명 객체가 특정 형태로 신뢰 당사자에게 전달되도록 요청하는 데 사용할 수 있습니다. 가능한 값은 none(기본값), indirect, direct 및 enterprise입니다.
- **extensions:** 특정 반환 값과 같은 추가 처리를 위한 선택적 요청입니다. 예:
    - _credProbs_ 생성된 자격 증명을 검색할 수 있는지 여부에 대한 정보를 요청합니다.
    - _prf_ 신뢰 당사자가 자격 증명과 연관된 의사 난수 함수(PRF)의 출력을 사용할 수 있도록 합니다.

### 2.2 Public Key Credential Request Options

PublicKeyCredentialRequestOptions는 어서션 단계(로그인)의 핵심 객체입니다. [WebAuthn 서버](#webauthn-server)에서 생성되어 반환됩니다.

```json
{
    "publicKeyCredentialRequestOptions": {
        "challenge": "pT7HMA-…dFPHk",
        "timeout": 500,
        "rpId": "passkeys.eu",
        "userVerification": "preferred",
        "allowCredentials": [],
        "extensions": []
    }
}
```

이 객체는 다음 속성을 포함합니다.

- **challenge, timeout, extensions:** [위](#creationoptions)를 참조하세요.
- **rpId:** 어서션 요청에 대한 신뢰 당사자의 식별자입니다. 섹션 [4.2 신뢰 당사자 ID (rpID)](#relying-party-id)를 참조하세요.
- **allowCredentials:** 인증이 허용되는 자격 증명의 선택적 목록으로, 호출자의 선호도를 내림차순으로 나타냅니다. 이 목록은 PublicKeyCredentialDescriptors로 채워집니다.
- **userVerification:** 작업 중 사용자 확인에 대한 요구 사항을 지정하기 위한 선택적 값입니다. 가능한 값은 preferred(기본값), required 또는 discouraged입니다.

### 2.3 증명

**증명** / 등록 세레모니 중에 인증기는 이 **등록 응답**을 반환합니다. [Passkeys Debugger](https://www.passkeys-debugger.io/)에서 직접 테스트해 볼 수 있습니다.

```json
{
    "authenticatorAttachment": "platform",
    "id": "JKZbixUfKN_aZtimefYT-OjH5dw",
    "rawId": "JKZbixUfKN_aZtimefYT-OjH5dw",
    "response": {
        "attestationObject": {
            "fmt": "none",
            "attStmt": {},
            "authData": {
                "rpIdHash": "PpZrl-Wqt-OFfBpyy2SraN1m7LT0GZORwGA7-6ujYkM",
                "flags": {
                    "userPresent": true,
                    "userVerified": true,
                    "backupEligible": true,
                    "backupStatus": true,
                    "attestedData": true,
                    "extensionData": false
                },
                "counter": 0,
                "aaguid": {
                    "raw": "fbfc3007-154e-4ecc-8c0b-6e020557d7bd",
                    "name": "iCloud Keychain"
                },
                "credentialID": "JKZbixUfKN_aZtimefYT-OjH5dw",
                "credentialPublicKey": "pQECAyYgASFYIPWLalDzyxIDmAADvfK8iNM5To50kh7TyPH-teEz8RMdIlgg3D7bPIWQJ8z-WFn3zdYZzJw9c7mhPdmflQqD9vV7efA",
                "parsedCredentialPublicKey": {
                    "keyType": "EC2 (2)",
                    "algorithm": "ES256 (-7)",
                    "curve": 1,
                    "x": "9YtqUPPLEgOYAAO98ryI0zlOjnSSHtPI8f614TPxEx0",
                    "y": "3D7bPIWQJ8z-WFn3zdYZzJw9c7mhPdmflQqD9vV7efA"
                }
            }
        },
        "clientDataJSON": {
            "type": "webauthn.create",
            "challenge": "k2p6f-upzP_hc6NZvmMAxiI0VSTeQIeXXVRGW62LTj0",
            "origin": "https://www.passkeys-debugger.io",
            "crossOrigin": false
        },
        "transports": ["hybrid", "internal"],
        "authenticatorData": "PpZrl-Wqt-OFfBpyy2SraN1m7LT0GZORwGA7-6ujYkNdAAAAAPv8MAcVTk7MjAtuAgVX170AFCSmW4sVHyjf2mbYpnn2E_jox-XcpQECAyYgASFYIPWLalDzyxIDmAADvfK8iNM5To50kh7TyPH-teEz8RMdIlgg3D7bPIWQJ8z-WFn3zdYZzJw9c7mhPdmflQqD9vV7efA",
        "publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9YtqUPPLEgOYAAO98ryI0zlOjnSSHtPI8f614TPxEx3cPts8hZAnzP5YWffN1hnMnD1zuaE92Z-VCoP29Xt58A",
        "publicKeyAlgorithm": -7
    },
    "type": "public-key",
    "clientExtensionResults": {}
}
```

**증명**에는 [attestationObject](#attestationObject), [algorithm](#algorithm) 및 [transport](#transport) 플래그와 같은 몇 가지 중요한 구성 요소가 포함되어 있습니다.

#### 2.3.1 attestationObject

![The attestationObject is part of the attestation in WebAuthn](https://www.corbado.com/website-assets/65fad76914987b84f3ecf4cd_cs_2_3_attestation_Object_min_12a3b9e5cc.png)

출처: [W3C의 WebAuthn 사양](https://www.w3.org/TR/webauthn-2/#attestation-object)

**attestationObject**는 CBOR 인코딩된 객체로, 새로 생성된 자격 증명, 공개 키 및 기타 관련 데이터에 대한 정보를 포함합니다.

- **fmt**는 패스키의 경우 일반적으로 "none"으로 평가됩니다.
- **attStmt**는 패스키의 경우 비어 있으며, 하드웨어 보안 키와 같은 다른 인증기의 경우 채워집니다.
- **authData**는 다음 데이터를 포함하는 값의 버퍼입니다.

![authData is a buffer of values, containing e.g. flags, counters and extensions](https://www.corbado.com/website-assets/65fc7c70babae11893e3e1e1_cs_2_3_auth_Data_min_7a7d39d083.png)

[확장](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API/WebAuthn_extensions)에 대해 자세히 알아보세요.

#### algorithm

패스키는 **COSE 알고리즘**으로 생성되며, [증명 객체](#attestation)의 parsedCredentialPublicKey의 **algorithm 속성**에 사용된 알고리즘을 나타냅니다.\
다음은 가장 관련성이 높은 COSE 알고리즘에 대한 개요입니다.

![Passkeys are generated with COSE algorithms](https://www.corbado.com/website-assets/65fade5ce80ed150f88b59fb_cs_2_3_COSE_algorithms_min_f0d1a5f931.png)

#### 2.3.2 transport

**transports** 속성은 인증기가 클라이언트와 통신할 수 있는 메커니즘을 나타냅니다. 일반적인 샘플 값 조합은 다음과 같습니다.

- **"transports": \["internal","hybrid"]**: 플랫폼 인증기(예: Face ID, Touch ID, Windows Hello) 또는 교차 기기 인증(QR 코드 및 Bluetooth 사용)을 통해 패스키를 사용할 수 있습니다.
- **"transports": \["internal"]**: 플랫폼 인증기(예: Face ID, Touch ID, Windows Hello)를 통해서만 패스키를 사용할 수 있습니다.
- **"transports" 속성이 설정되지 않음:** 어떠한 표시도 제공하지 않는 기본 동작입니다.

### 2.4 어서션

**어서션** / 로그인 세레모니 중에 인증기는 이 **로그인 응답**을 반환합니다. [Passkeys Debugger](https://www.passkeys-debugger.io/)에서 직접 테스트해 볼 수 있습니다.

```json
{
    "id": "JKZbixUfKN_aZtimefYT-OjH5dw",
    "rawId": "JKZbixUfKN_aZtimefYT-OjH5dw",
    "type": "public-key",
    "authenticatorAttachment": "platform",
    "response": {
        "authenticatorData": {
            "rpIdHash": "PpZrl-Wqt-OFfBpyy2SraN1m7LT0GZORwGA7-6ujYkM",
            "flags": {
                "userPresent": true,
                "userVerified": true,
                "backupEligible": true,
                "backupStatus": true,
                "attestedData": false,
                "extensionData": false
            },
            "counter": 0
        },
        "clientDataJSON": {
            "type": "webauthn.get",
            "challenge": "GCVkITWbe2l2dttsn_DgJYvH9QPHPDo0ygWgcgI6B7U",
            "origin": "https://www.passkeys-debugger.io",
            "crossOrigin": false,
            "other_keys_can_be_added_here": "do not compare clientDataJSON against a template. See https://goo.gl/yabPex"
        },
        "signature": "MEQCIA-orC8N2KKWOxyY17BWP8lB-Be5to9btXRnJZf2SLhXAiBGxJe5Eu5LwOTbsyzAYmIXHOhlC3pN7s7Q1fRLvEW57g",
        "userHandle": "_FKz1uwqmR_3yGq6hJntzoIFwFC_d1u_53YRELh0KlE"
    }
}
```

**어서션**에는 flags, signature 및 userHandle과 같은 몇 가지 중요한 구성 요소가 포함되어 있습니다.

#### 2.4.1 flags

다음은 가장 관련성이 높은 **플래그**와 그 조합에 대한 개요입니다.

![The most important flags are userPresent, userVerified, backupEligible, backupStatus](https://www.corbado.com/website-assets/65fc7ca5a6a6fb1f3e66b514_cs_2_4_flags_min_19e5ddc4ce.png)

#### 2.4.2 signature

**서명**은 로그인하려는 사용자가 실제로 개인 키를 가지고 있는지 확인하는 데 사용됩니다. 서명은 authenticatorData와 clientDataHash(즉, ClientDataJSON의 SHA-256 버전)를 연결하고 그 결과를 (인증기 내의) 개인 키로 서명하여 생성됩니다. 공개 키로 확인하기 위해 authenticatorData와 clientDataHash도 연결합니다. 확인 결과가 참을 반환하면 인증에 성공한 것입니다.

![The signature is used to verify the private key](https://www.corbado.com/website-assets/65fae2ad96200e9576992209_cs_2_4_signature_min_36b9b8ccbe.png)

#### 2.4.3 userHandle

**userHandle**은 실제 user_id입니다. user_id에 대한 자세한 내용은 섹션 [**4.1 데이터베이스 스키마**](#database-schema)를 참조하세요.

### 2.5 authenticatorSelection

**authenticatorSelection** 객체를 통해 서버는 다음 값을 사용하여 인증기 및 자격 증명 생성에 대한 설정을 지시할 수 있습니다.

#### 2.5.1 authenticatorAttachment

- **Platform:** 인증기가 클라이언트의 플랫폼에 연결되어 있으므로 제거할 수 없습니다.
- **Cross-platform:** 인증기가 클라이언트의 플랫폼에 바인딩되어 있지 않으며 여러 기기에서 사용할 수 있습니다.

#### 2.5.2 residentKey

- **Required:** 인증기는 상주 키를 생성해야 합니다(불가능한 경우 작업이 실패해야 함).
- **Preferred:** 인증기는 상주 키 생성을 시도해야 합니다(불가능한 경우 비상주 키를 생성해야 함).
- **Discouraged:** 인증기는 비상주 키를 생성해야 합니다(불가능한 경우 작업이 실패해야 함).

> **상주 키(검색 가능한 자격 증명이라고도 함):** 상주 키는 인증기에 저장되고 인증 중에 검색됩니다. 이렇게 하면 클라이언트가 가능한 키 목록을 검색할 수 있으며, 이것이 텍스트 패스키로 Conditional UI를 구현할 때 상주 키가 필요한 이유입니다.
> **비상주 키(검색 불가능한 자격 증명이라고도 함):** 비상주 키의 경우 자격 증명 ID가 서버에 저장되고 인증 중에 제공됩니다. 자격 증명 ID는 내부 구조가 구현에 따라 달라지는 [불투명한 식별자](https://www.w3.org/TR/webauthn-3/#sctn-credential-id)입니다. 인증기는 개인 키를 직접 저장하거나 암호화된 키 래핑을 사용하거나 내부 비밀에서 키를 파생시킬 수 있습니다. 정확한 메커니즘은 인증기 구현에 따라 다릅니다.

#### 2.5.3 userVerification

- **Required:** 작업에서 사용자를 확인해야 합니다.
- **Preferred:** 작업에서 사용자를 확인해야 하지만, 확인 없이도 진행할 수 있습니다(표준 옵션).
- **Discouraged:** 작업에서 사용자를 확인해서는 안 됩니다.

> **경고:** "**Preferred**"로 설정된 경우 사용자 또는 사용자의 기기는 인증 프로세스에서 사용자 확인을 건너뛸 수 있습니다(자세한 내용은 이 [기사](https://web.dev/articles/passkey-form-autofill)를 참조하세요).

## 3. Conditional UI

**Conditional UI**(패스키 자동 완성)는 사용자가 신뢰 당사자에 등록된 상주 키를 가지고 있을 때 사용 가능한 패스키를 사용자를 위한 선택 드롭다운에 표시합니다. 패스키의 사용성을 향상시키지만 추가 개발 노력이 필요하며 모든 OS / 브라우저 조합에서 사용할 수 있는 것은 아닙니다.

### 3.1 Conditional UI를 사용한 로그인 흐름

![Process flow of a login with Conditional UI in WebAuthn](https://www.corbado.com/website-assets/65fae71a75d50f6ba14041d9_cs_3_1_conditional_ui_flow_min_394a12f521.png)_일반적인 로그인과 마찬가지로 Conditional UI도 PublicKeyCredentialRequestOptions 및 어서션 객체를 사용합니다._

### 3.2 기기 호환성

Conditional UI는 (아직) 모든 운영 체제 및 브라우저 조합에서 사용할 수 있는 것은 아닙니다. 다음은 현재 브라우저 지원 범위(2024년 3월 기준)에 대한 개요입니다.

![Table that shows the availability of Conditional on OS/browser combinations](https://www.corbado.com/website-assets/65fae8d6321e72be11445913_cs_3_2_conditional_ui_compatibility_min_d5767f13b3.png)

최신 개요는 [이 웹사이트](https://caniuse.com/mdn-api_publickeycredential_isconditionalmediationavailable_static)를 참조하세요.

### 3.3 코드 예제

#### 3.3.1 Conditional UI 메소드

Conditional UI 메소드의 전체적이고 간결한 코드는 다음과 같습니다.

```html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Conditional UI</title>
    </head>
    <body>
        <input type="text" id="username" autocomplete="username webauthn" />

        <script>
            async function passkeyLogin() {
                try {
                    // WebAuthn 서버에서 챌린지를 포함한 요청 옵션을 검색합니다.
                    let options = await WebAuthnClient.getPublicKeyRequestOptions();

                    const credential = await navigator.credentials.get({
                        publicKey: options.publicKeyCredentialRequestOptions,
                        mediation: "conditional",
                    });

                    const userData = await WebAuthnClient.sendSignedChallenge(credential);
                    window.location.href = "/logged-in";
                } catch (error) {
                    console.log(error);
                }
            }

            passkeyLogin();
        </script>
    </body>
</html>
```

#### 3.3.2 브라우저 호환성 검사

Conditional UI는 **상주 키** / 검색 가능한 자격 증명에서만 작동합니다.\
Conditional UI 로그인을 시작하려면 **별도의 서버 엔드포인트**를 제공하는 것이 좋습니다.\
클라이언트는 여러 요구 사항을 충족해야 합니다.

- 브라우저가 Conditional UI를 지원해야 합니다([3.2 기기 호환성](#device-compatibility) 참조).
- JavaScript가 활성화되어야 하고 웹 페이지는 HTML 입력 필드를 제공해야 합니다.
- 타임아웃 매개변수는 무시해야 합니다.

오류를 방지하려면 서버는 먼저 이 함수를 사용하여 클라이언트의 가용성을 테스트해야 합니다. 실제 트래픽에서 감지 및 수명 주기 문제는 종종 `NotAllowedError` 또는 `AbortError`로 나타납니다. 네이티브 자격 증명 관리자 패스키 오류를 포함하여 예상되는 오류와 예상치 못한 오류를 분류하려면 이 WebAuthn 오류 가이드를 사용하세요.

```javascript
// 출처: https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/isConditionalMediationAvailable#examples

// `window.PublicKeyCredential`의 가용성은 WebAuthn을 사용할 수 있음을 의미합니다.
if (window.PublicKeyCredential && PublicKeyCredential.isConditionalMediationAvailable) {
    // 조건부 중재가 가능한지 확인합니다.
    const isCMA = await PublicKeyCredential.isConditionalMediationAvailable();
    if (isCMA) {
        // WebAuthn 인증 시작 엔드포인트 호출

        let options = await WebAuthnClient.getPublicKeyRequestOptions();

        const credential = await navigator.credentials.get({
            publicKey: options.publicKeyCredentialRequestOptions,
            mediation: "conditional",
        });
        /*
    ...
    */
    }
}
```

#### 3.3.3 입력 필드의 자동 완성 토큰

입력 필드는 진행 중인 요청에 패스키를 채우도록 클라이언트에 신호를 보내는 HTML 자동 완성 토큰을 수신해야 합니다. 패스키 외에도 자동 완성 토큰은 사용자 이름 및 비밀번호와 같은 기존 토큰과 페어링될 수 있습니다.

- autocomplete="username webauthn": 패스키 표시 외에도 사용자 이름 자동 완성을 제안합니다.
- autocomplete="current-password webauthn": 패스키 표시 외에도 비밀번호 자동 완성을 추가로 요청합니다.

```html
<label for="name">사용자 이름:</label>
<input type="text" name="name" autocomplete="username webauthn" />
<label for="password">비밀번호:</label>
<input type="password" name="password" autocomplete="current-password webauthn" />
```

## 4. WebAuthn 서버

### 4.1 데이터베이스 스키마

WebAuthn 서버에 대한 필수적이거나 표준화된 데이터베이스 스키마는 없습니다. 그러나 이 예제 데이터베이스 스키마를 사용하여 필수 정보를 저장하고 WebAuthn 서버의 모든 기능을 제공할 수 있습니다.

![Example database schema for a WebAuthn server, containing data for 'user' and 'credential](https://www.corbado.com/website-assets/65fc7cda64ff7798cdbb2dfc_cs_4_1_database_schema_min_8ac4536120.png)_굵게 표시된 속성은 최소한의 실행 가능한 구현에 필수적이며, 다른 속성은 선택적이지만 유용한 기능에만 필요합니다._

#### 4.1.1 인증 관련 데이터

- **Credential ID:** 패스키를 등록하는 동안 인증기에서 생성되는 고유 ID입니다. 패스키와 연관된 실제 사용자 계정을 찾는 데 사용해야 합니다. 추가로 (user_id의) userHandle을 비교하여 인증에 사용된 계정을 검증해야 합니다. 시간이 지남에 따라 변경될 수 있으므로 비교를 위해 user.name 속성을 사용하지 마세요.
- **User ID (user_id):** 시스템에서 사용자 계정을 나타내기 위해 신뢰 당사자가 지정한 고유 ID입니다. 어서션 객체 내에서 userHandle로 반환됩니다.

#### 4.1.2 패스키 표시 및 선택을 위한 메타데이터:

- **User DisplayName (user.displayName):** 일반적으로 사용자의 전체 이름인 사용자 친화적이고 읽기 쉬운 이름입니다. 사용자에게 표시되지만 인증 중에는 사용되지 않습니다.

- **User Name (user.name):** 일반적으로 이메일 주소 또는 사용자 이름인 고유하고 읽기 쉬운 이름입니다. 사용자에게 표시될 수 있지만 인증 중에는 사용되지 않습니다.

### 4.2 신뢰 당사자 ID (rpId)

**신뢰 당사자 ID(rpID)**는 패스키 내에 저장된 도메인으로, 패스키가 올바른 도메인(브라우저 URL, 네이티브 앱의 경우 이 기사 참조)에서만 작동하도록 보장합니다. 인증 중에 rpID는 브라우저 URL에 대해 확인되며 다음 두 가지 경우에만 허용됩니다.

1. URL이 rpId와 정확히 일치하거나
2. URL이 rpId와 일치하는 하위 도메인이고 상위 도메인이 공개 접미사 목록에 없는 경우

다음은 허용되거나 허용되지 않는 조합의 예입니다.

![Examples for allowed and disallowed combinations of Relying Party IDs](https://www.corbado.com/website-assets/65fc7d099bf36909d7f40495_cs_4_2_rpid_examples_min_55f5750e90.png)

## 5. 유용한 웹사이트 및 도구

다음은 패스키 구현에 유용한 도구 및 웹사이트 목록입니다.

- [**Passkeys Debugger:**](https://www.passkeys-debugger.io/) WebAuthn 응답을 JSON으로 디버깅하고 다양한 옵션으로 WebAuthn 작업을 테스트하기 위한 도구입니다.
- [**Passkeys Glossary:**](https://www.corbado.com/glossary) 패스키 관련 용어 및 개념 설명
- [**WebAuthn Specification:**](https://www.w3.org/TR/webauthn-2/) 공식 WebAuthn 사양입니다.
- [**Chrome Device Log:**](http://chrome://device-log) 기기의 WebAuthn 작업 로그를 표시하는 도구입니다(`chrome://device-log`를 통해 Chrome에서만 사용 가능).

기술적 구현을 넘어 패스키 UX를 최적화하는 전략은 패스키 생성 모범 사례 및 패스키 로그인 모범 사례 가이드를 참조하세요.

단 몇 줄의 코드로 모든 애플리케이션에 패스키를 구현하려면 [Corbado Complete](https://docs.corbado.com/start)(신규 앱의 경우) 또는 [Corbado Connect](https://www.corbado.com/enterprise)(기존 앱의 경우)를 사용할 수도 있습니다.

## 자주 묻는 질문

### 내 웹 앱에서 패스키 자동 완성을 위해 Conditional UI를 어떻게 구현하나요?

Conditional UI는 인증을 시작하기 전에 `PublicKeyCredential.isConditionalMediationAvailable()`을 통해 브라우저 지원 여부를 확인해야 합니다. 입력 필드는 `autocomplete="username webauthn"` HTML 토큰을 포함해야 하며 사용자는 상주 키(검색 가능한 자격 증명)를 등록해야 합니다. Conditional UI 로그인 흐름을 처리하기 위해 별도의 서버 엔드포인트를 사용하는 것이 좋습니다.

### WebAuthn 인증을 지원하려면 데이터베이스에 최소한 어떤 데이터를 저장해야 하나요?

최소한 등록 중에 인증기에서 생성된 Credential ID와 어서션 객체에서 userHandle로 반환되는 User ID(user_id)를 저장해야 합니다. Credential ID를 사용하여 연관된 사용자 계정을 찾고 userHandle을 비교하여 인증을 확인합니다. 시간이 지남에 따라 변경될 수 있으므로 비교를 위해 user.name을 사용하지 마세요.

### WebAuthn에서 상주 키와 비상주 키의 차이점은 무엇인가요?

상주 키(검색 가능한 자격 증명)는 인증기 자체에 저장되고 인증 중에 검색되며, 이는 Conditional UI가 작동하는 데 필요합니다. 비상주 키는 자격 증명 ID를 서버에 저장하고 인증 중에 인증기로 보냅니다. authenticatorSelection의 residentKey 필드는 "required", "preferred" 또는 "discouraged" 값으로 이 동작을 제어합니다.

### userVerification은 어떻게 작동하며 "preferred"로 설정할 때의 위험은 무엇인가요?

userVerification 필드는 로그인 중에 인증기가 사용자를 확인해야 하는지 여부를 제어하며 "required", "preferred"(기본값) 또는 "discouraged" 값을 허용합니다. "preferred"로 설정하면 사용자 또는 사용자의 기기가 인증 프로세스 중에 확인을 완전히 건너뛸 수 있어 보안이 약화될 수 있습니다. "required"로 설정하면 인증이 완료되기 전에 항상 확인이 발생합니다.
