1. 소개
이 섹션은 규범적이지 않습니다.
웹사이트에 로그인하는 것은 있어야 할 때보다 더 어렵습니다. 사용자 에이전트는 여러 방식으로 경험을 개선할 수 있는 고유한 위치에 있으며, 대부분의 최신 사용자 에이전트는 브라우저에 일부 자격 증명 관리 기능을 네이티브로 제공함으로써 이를 인식해 왔습니다. 예를 들어 사용자들은 웹사이트의 사용자 이름과 비밀번호를 저장할 수 있습니다; 이러한 credentials은 이후 로그인 양식에 자동완성되지만, 성공률은 다양합니다.
코드(autocomplete)
속성은 선언적 메커니즘을 제공하여 웹사이트가 사용자 에이전트와 협력해 특정 필드를 "username" 또는 "password"로 표시함으로써 로그인 양식을 감지하고 채우는 능력을 향상시킬
수 있게 합니다. 사용자 에이전트는 마크업에 이러한 세부사항을 제공할 시간이 없었던 웹사이트와 함께 작동하기 위해 다양한 탐지 휴리스틱을 구현합니다.
이러한 휴리스틱과 선언적 탐지의 조합은 비교적 잘 작동하지만, 현 상태는 탐지가 문제인 큰 공백을 남깁니다. 자격 증명을 XMLHttpRequest를
통해 제출하는 것과 같은 드문 로그인 메커니즘을 사용하는 사이트는 신뢰성 있게 탐지하기 어렵고, 사용자가 연합 신원 제공자(federated identity provider)를 사용해
인증하기를 원하는 경우가 점점 흔해지는 상황도 마찬가지입니다. 웹사이트가 사용자 에이전트의 credential manager와 보다 직접적으로 상호작용할 수 있도록 허용하면, 한편으로는 credential
manager의 정확도를 높일 수 있고, 다른 한편으로는 연합 로그인에서 사용자를 도울 수 있습니다.
이 사용 사례들은 § 1.1 Use Cases 및 Credential Management: Use Cases and Requirements에서 더 자세히 다룹니다; 이 명세는 웹사이트가 사용자의 credentials을 요청하고 사용자가 성공적으로 로그인했을 때 사용자 에이전트에게 자격 증명 저장을 요청할 수 있도록 하는 Credential Manager API를 정의함으로써 해당 문서가 제시한 많은 요구사항을 해결하려고 합니다.
참고: 여기서 정의한 API는 의도적으로 작고 단순합니다: 이것 자체로 인증을 제공하려는 것이 아니라, 기존 사용자 에이전트들이 구현한 기존 credential managers에 대한 인터페이스를 제공하는 것으로 제한됩니다. 그 기능은 벤더나 작성자 쪽의 큰 노력 없이도 지금 당장 가치가 있습니다. 물론 더 많은 것을 할 수 있는 여지는 분명히 있습니다. 지금은 보류한 몇 가지 생각은 § 9 Future Work를 참조하십시오; 이후 이 API의 반복에서 탐구될 수 있습니다.
1.1. 사용 사례
최신 사용자 에이전트는 일반적으로 사용자가 웹사이트에 로그인할 때 비밀번호를 저장할 수 있도록 하고, 사용자가 재방문할 때 로그인 폼에 비밀번호를 완전히 또는 부분적으로 자동으로 채워주는 기능을 제공합니다. 웹사이트 입장에서는 이러한 동작을 전혀 인지하지 못합니다: 비밀번호가 저장되었는지, 채워졌는지 알지 못합니다. 이는 장단점이 있습니다. 한편으로 사용자 에이전트의 비밀번호 관리자는 사이트 협조 여부와 관계없이 동작하므로 사용자에게 매우 좋습니다. 반면, 비밀번호 관리자의 동작은 로그인 폼, 비밀번호 변경 폼 등을 감지하고 채우기 위한 휴리스틱이 뒤섞인 불안정하고 독점적인 조합입니다.
현 상태에서 특히 문제되는 몇 가지가 있습니다:
-
사용자 에이전트는 연합 신원 제공자를 사용하는 사용자를 돕는 데 매우 어려움을 겪습니다. 사용자 이름/비밀번호 폼 제출 감지는 비교적 간단하지만, 제3자를 통한 로그인 감지는 신뢰성 있게 잘 수행하기 어렵습니다. 웹사이트가 전형적인 연합 로그인 동작에 수반되는 리디렉션의 의도를 사용자 에이전트에 알려줄 수 있다면 좋을 것입니다.
-
마찬가지로, 사용자 에이전트는 단순 사용자 이름/비밀번호 폼보다 더 특이한 로그인 메커니즘을 감지하는 데 어려움을 겪습니다. 저자들은 점점 더
XMLHttpRequest또는 유사한 메커니즘을 통해 비동기적으로 사용자를 로그인시키며, 이는 경험을 개선하고 프레젠테이션을 더 많이 제어하기 위함입니다. 사용자를 위해 좋은 일이지만, 사용자 에이전트가 비밀번호 관리자를 통합하기에는 어렵습니다. 웹사이트가 자신이 사용하는 로그인 메커니즘을 사용자 에이전트가 이해하도록 도울 수 있다면 좋을 것입니다. -
마지막으로, 비밀번호 변경은 웹사이트가 자격 증명이 변경되었음을 명시적으로 사용자 에이전트에 알렸다면 더 잘 지원될 수 있습니다.
2. 핵심 API
개발자 관점에서 자격 증명은 특정
동작의 인증 결정을 내릴 수 있게 하는 객체입니다. 이 섹션에서는 Credential
인터페이스를 기반 클래스로 하여, 이 문서 및 다른 문서에서 정의된 자격 증명을 위한 확장 가능한 API 집합과 navigator.credentials.*
를 통해 개발자가 자격 증명을 얻을 수 있도록 정의합니다.
여러 자격 증명 유형은 각각 JavaScript에서 상속을 통해, 직접 또는 간접적으로 Credential
인터페이스를 구현합니다. 이 문서에서는 PasswordCredential
및 FederatedCredential
두 가지 인터페이스를 정의합니다. 다른 명세(예: [WEBAUTHN])는 다른
자격 증명 유형을 정의합니다.
자격 증명은 특정 origin에 대해 유효하다고 합니다. 이는 해당 origin에서 인증으로 받아들여지는 경우를 의미합니다. 자격 증명이 특정 시점에 유효하더라도, 사용자 에이전트는 같은 자격 증명이 앞으로도 계속 유효할 것이라고 가정할 수 없습니다. 그 이유는 다음과 같습니다.
-
비밀번호 자격 증명은 계정 소유자가 비밀번호를 변경하면 더 이상 유효하지 않을 수 있습니다.
-
SMS로 받은 토큰으로 만든 자격 증명은 한 번만 사용할 수 있을 가능성이 높습니다.
일회용 자격 증명은 자격 증명 소스에서 생성되며, 이는 개인키, 연합 계정 접근, 특정 전화번호로 SMS를 받을 수 있는 능력 등일 수 있습니다. 자격 증명 소스는 JavaScript에 노출되지 않으며, 이 명세에서 명시적으로 표현되지 않습니다. 모델을 통합하기 위해, 비밀번호 자체를 하나의 자격 증명 소스로 간주하며, 이는 비밀번호 자격 증명을 만들기 위해 단순히 복사됩니다.
UA는 유효한 자격 증명이 두 번째 사용에서도 유효할 것이라거나, 유효한 자격 증명을 생성한 자격 증명 소스가 앞으로도 유효한 자격 증명을 지속적으로 생성할 수 있으리라고 가정할 수
없지만, 후자가 전자보다 더 가능성이 높습니다. 과거에 유효했던 자격 증명을 (store()
를 통해) 기록함으로써, UA는 앞으로 사용자가 사용할 수 있는 유효한 자격 증명 소스를 더 잘 제공할 수 있게
됩니다.
2.1. 인프라스트럭처
A 자격 증명 관리자는 애플리케이션, 하드웨어 장치 또는 서비스로서 저장, 정리, 관리하고 선택할 수 있게 하는 자격 증명을 다룹니다. 예시 자격 증명 관리자에는 디지털 지갑, 비밀번호 관리자, 그리고 passkey 관리자가 포함됩니다.
사용자 에이전트는 내부적으로 자격 증명 저장소를 반드시 제공해야 하며, 이는 특정 벤더에 종속된 불투명한 저장 메커니즘으로 어떤 자격 증명이 유효한지를 기록합니다. 이는 자격 증명에 대한 접근과 지속성에 대해 다음과 같은 기능을 제공합니다:
-
자격 증명 저장 — 나중에 검색할 수 있도록 자격 증명을 저장합니다. 이 기능은 자격 증명을 받아 자격 증명 저장소에 삽입합니다.
-
자격 증명 목록 검색. 이 기능은 임의의 필터를 받아 필터와 일치하는 자격 증명 집합을 반환합니다.
또한, 자격 증명
저장소는 prevent silent access 플래그를 origin에 대해 유지해야 합니다(명시되지 않는 한 true로 설정됩니다). 플래그가
true로 설정된 origin은 사용자 중재가 필요함으로 간주됩니다。
참고: 사용자 중재의 중요성은 § 5 사용자 중재에서 더 자세히 논의됩니다。
참고: 자격 증명 저장소는 사용자 에이전트가 이 문서에서 지정한 API를 구현하는 내부 구현 세부사항이며 웹에 직접 노출되지 않습니다. 특정 자격 증명 유형을 지원하기 위해 다른 문서에서 더 많은 기능이 지정될 수 있습니다。
이 문서는 알고리즘과 문장에 사용되는 여러 기본 개념에 대해 Infra Standard에 의존합니다 [INFRA]。
각 environment settings object에는 연관된 활성 자격 증명 유형이 있으며, 이는 처음에는 비어 있는 집합입니다。
2.1.1. 인프라스트럭처 알고리즘
2.1.1.1. 상위와 동일 출처
environment settings object (settings)가
상위와 동일 출처인 경우, 다음 알고리즘이 true를 반환합니다:
-
settings의 관련 글로벌 객체에 연결된 Document가 없으면,
false를 반환한다. -
document를 settings의 관련 글로벌 객체의 연결된 Document로 한다.
-
document에 브라우징 컨텍스트가 없으면
false를 반환한다. -
origin을 settings의 origin으로 한다.
-
navigable을 document의 node navigable로 한다.
-
navigable이 null이 아닌 parent를 가질 때 반복한다:
-
navigable을 navigable의 parent로 설정한다.
-
navigable의 active document의 origin이 origin과 동일 출처가 아니면,
false를 반환한다.
-
-
true를 반환한다.
2.1.2. 자격 증명 유형 레지스트리
이 레지스트리는 자격 증명 유형 (예: [[type]]
값)을 해당 유형에 연관된 다양한 값에 매핑합니다. 예시: 옵션 멤버 식별자 (공식적으로 딕셔너리 멤버 식별자)로, CredentialCreationOptions
및 CredentialRequestOptions
(즉, "options dictionaries")에서 명세됩니다.
참고: 이 레지스트리는 관련 자격 증명 인터페이스 객체 알고리즘에서 사용됩니다.
| 자격 증명 유형 (알파벳 순) | 옵션 멤버 식별자 | 적절한 인터페이스 객체 | Get Permissions Policy | Create Permissions Policy | 명세 | 요청자 연락처 |
|---|---|---|---|---|---|---|
| digital-credential | digital | DigitalCredential
| digital-credentials-get | null | [DIGITAL-CREDENTIALS] | WICG |
| federated | federated | FederatedCredential
| null | null | 이 명세서: § 4 연합 자격 증명 | W3C |
| identity | identity | IdentityCredential
| identity-credentials-get | null | [FEDCM] | W3C |
| otp | otp | OTPCredential
| otp-credentials | null | [WEB-OTP] | WICG |
| password | password | PasswordCredential
| null | null | 이 명세서: § 3 비밀번호 자격 증명 | W3C |
| public-key | publicKey | PublicKeyCredential
| publickey-credentials-get | publickey-credentials-create | [WEBAUTHN] | W3C |
2.1.2.1. 등록 항목 요구사항 및 갱신 프로세스
-
각 레지스트리 항목은 딕셔너리 멤버 식별자(레지스트리에서는 옵션 멤버 식별자로 알려짐)를 명시해야 하며, 이는
CredentialCreationOptions및CredentialRequestOptions의 확장에서 사용됩니다. -
각 레지스트리 항목은 적절한 인터페이스 객체 식별자를 해당 자격 증명 유형에 대해 명시해야 합니다.
-
각 레지스트리 항목은 Get Permissions Policy 권한을 명시해야 하며, 이는 자격 증명 요청 시 사용하거나, 명시되지 않은 경우 null로 설정합니다.
-
각 레지스트리 항목은 Create Permissions Policy 권한을 명시해야 하며, 이는 자격 증명 생성 시 사용하거나, 명시되지 않은 경우 null로 설정합니다.
-
각 레지스트리 항목에는 자격 증명 유형 및 딕셔너리 멤버 식별자를 정의하는 공개 명세에 대한 링크가 포함되어야 합니다.
-
각 레지스트리 항목의 명세에는 요청자 연락처 정보가 포함되어야 합니다.
이 레지스트리의 갱신은 자격 증명 유형의 항목 추가, 변경 또는 삭제입니다. 누구나 webappsec-credential-management 저장소에 풀 리퀘스트로 갱신 요청을 할 수 있습니다. 웹 애플리케이션 보안 작업 그룹에서 다가오는 회의 안건에 올리고 요청자에게 알립니다. 요청의 검토 및 결정은 W3C 웹 애플리케이션 보안 작업 그룹의 합의에 따릅니다. 의장이 결과를 요청자에게 알리고 레지스트리를 갱신합니다.
2.2.
Credential 인터페이스
[Exposed =Window ,SecureContext ]interface {Credential readonly attribute USVString id ;readonly attribute DOMString type ;static Promise <boolean >isConditionalMediationAvailable (); };
id, USVString 타입, 읽기 전용(readonly)-
자격 증명(credential)의 식별자입니다. 이 식별자에 대한 요구 사항은 각 자격 증명 유형마다 다릅니다. 예를 들어, username/password 쌍의 경우 username을 나타낼 수 있습니다.
type, DOMString 타입, 읽기 전용-
이 attribute의 getter는 객체의 인터페이스 객체의
[[type]]슬롯의 값을 반환합니다. 이 슬롯은 이 객체가 나타내는 자격 증명 타입을 지정합니다. isConditionalMediationAvailable()-
Promise를 반환합니다. 이 Promise는 사용자가conditional방식의 자격 증명 요청 중재를 자격 증명 타입에 대해 지원하는 경우에만true로 resolve, 그렇지 않으면false로 resolve됩니다.Credential의isConditionalMediationAvailable()의 기본 구현:-
resolve된 promise로
false를 반환합니다.
conditional방식을 지원하는 자격 증명 타입에 대한 명세는 반드시 이 함수를 override하여 resolve가true를 반환하도록 해야 합니다.Note: 이 함수가 없는 경우,
conditional중재는 해당 자격 증명 타입에서 지원되지 않습니다. -
[[type]]-
Credential인터페이스 객체에는[[type]]이라는 내부 슬롯이 있으며, 이는 자격 증명 타입을 나타내는 문자열을 저장합니다. 별도 지정이 없으면 이 슬롯의 값은 빈 문자열입니다. § 2.1.2 Credential Type Registry에서 자격 증명 타입 목록을 확인하세요.Note:
[[type]]슬롯의 값은 특정 인터페이스를 구현하는 모든 자격 증명에서 동일하므로, 개발자는obj.type의 반환값으로 해당Credential의 종류를 명확하게 알 수 있습니다. [[discovery]]-
Credential인터페이스 객체에는[[discovery]]라는 내부 슬롯이 있으며, 사용자 에이전트가 특정 타입의 자격 증명을 수집할 수 있는 메커니즘을 나타냅니다. 해당 값은 "credential store" 또는 "remote"입니다. 전자는 모든 이용 가능한 자격 증명 정보가 사용자 에이전트의 자격 증명 저장소 에 저장되어 있음을 의미하고, 후자는 사용자 에이전트가 외부 장치나 서비스를 통해 자격 증명 저장소에 명시적으로 나타난 것 이외의 자격 증명도 탐색할 수 있음을 의미합니다.
Tobie/Dominic에게 여기 및 § 2.5.1 자격 증명 요청(Request a Credential) 등에서 인터페이스 객체 관련 논의를 확인하세요. 용어가 정확한지 확신이 없습니다. 인터페이스 프로토타입 객체일 수도 있습니다.
일부 Credential
객체는 Origin Bound가 될 수 있습니다. 이러한 객체에는 [[origin]]
이라는 내부 슬롯이 존재하며, 이는 해당 origin을 저장합니다. 이 정보는 Credential이
효과적(Effective)으로 사용될 수 있는 origin입니다.
2.2.1.
Credential 내부 메서드
Credential
인터페이스 객체는 여러 개의 내부 메서드를
지원하며,
Credential
객체의 조회 및 저장을 돕습니다. 이 섹션에서
명시한 대로, 기본적으로 "no-op"(아무 작업도 하지 않음) 구현을 제공합니다.
별도 명시가 없는 한, Credential
을(를) 상속하는 인터페이스에 대해 생성되는 각
인터페이스 객체(interface object)는
적어도 하나 이상의 내부 메서드를 구현해야 하며,
각 자격 증명(credential) 타입에
적합하게 Credential의
기본 구현을 오버라이드해야 합니다. 예시로
§ 3.2 PasswordCredential 인터페이스,
§ 4.1 FederatedCredential 인터페이스,
그리고 [WEBAUTHN]가 있습니다.
2.2.1.1. [[CollectFromCredentialStore]] 내부 메서드
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
는 origin, CredentialRequestOptions
및 부울 값
(호출자의 environment settings object가 조상과 동일
출처(same-origin)일 때만 true)
을 인자로 호출됩니다.
이 알고리즘은 사용자 에이전트의 자격 증명 저장소에서 주어진 옵션에 일치하는 Credential
객체 집합을 반환합니다. 일치하는 Credential
객체가 없다면,
반환되는 집합은 비어 있게 됩니다.
Credential의
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
기본 구현:
-
빈 집합을 반환한다.
2.2.1.2. [[DiscoverFromExternalSource]] 내부 메서드
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
는 병렬로 호출되며, origin, CredentialRequestOptions
객체,
그리고 호출자의 environment settings object가
조상과 동일 출처(same-origin)일 경우에만 true인 불리언 값을 인자로 받습니다.
주어진 옵션에 따라 반환 가능한 경우 Credential을
반환하고, 사용 가능한 자격 증명이 없으면 null을 반환하며, 찾기에 실패하면 오류를 throw합니다(예: 잘못된 옵션이 TypeError를
발생시킬 수 있음).
만약 이 Credential이(가)
한 번만 사용 가능하거나 제한된 시간 동안만 유효하다면,
이 메서드는 자격 증명 소스로부터 새로운
자격 증명을 생성할 책임이
있습니다.
Credential의
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
기본 구현:
-
null을 반환한다.
2.2.1.3. [[Store]] 내부 메서드
[[Store]](credential, sameOriginWithAncestors)
는 병렬로 호출되며, Credential과
호출자의
environment settings object가 조상과 동일
출처(same-origin)일 때만 true인 불리언 값을 인자로 받습니다.
이 알고리즘은 Credential이
자격 증명
저장소에 영구 저장(persist)되면 반환됩니다.
Credential의
[[Store]](credential, sameOriginWithAncestors)
기본 구현:
-
NotSupportedError를 throw한다.
2.2.1.4. [[Create]] 내부 메서드
[[Create]](origin, options, sameOriginWithAncestors)
는 병렬로 호출되며, origin, CredentialCreationOptions,
그리고 호출자의
environment settings object가 조상과 동일
출처(same-origin)일 때에만 true인 불리언 값을 인자로 받습니다.
이 알고리즘은 다음 중 하나를 수행합니다:
-
Credential을 생성하거나, -
자격 증명을 생성하지 않고
null을 반환하거나, -
예외 상황(예: 잘못된 옵션으로
TypeError가 발생하는 경우) 에서 오류를 throw합니다.
Credential
을 생성할 때, global object
를 받아 interface object
를 반환하는 알고리즘을 리턴합니다. 이 알고리즘은 반드시 task에서 호출되어야 합니다.
참고: 이 알고리즘의 단계는 각 자격 증명 타입별로 정의되어 있습니다.
Credential의
[[Create]](origin, options, sameOriginWithAncestors)
기본 구현:
-
null을 반환한다.
2.2.2.
CredentialUserData 믹스인
일부 Credential
객체에는 사용자에게 자격 증명
선택기에서 인간이 읽을 수 있는 구분(식별) 메커니즘을 제공하기 위해 친숙한 이름과 아이콘 정보를 포함합니다:
[SecureContext ]interface mixin {CredentialUserData readonly attribute USVString name ;readonly attribute USVString iconURL ; };
name, USVString 타입, 읽기 전용-
자격 증명과 연관된 이름으로, 자격 증명 선택기에 표시되는 사용자 친화적인 공개 이름입니다.
iconURL, USVString 타입, 읽기 전용-
자격 증명에 대한 이미지를 가리키는 URL로, 자격 증명 선택기에 표시합니다. 이 URL은 반드시 신뢰할 수 있는 URL이어야 합니다.
2.3.
navigator.credentials
개발자는 Credential을(를)
조회하고, 사용자 에이전트의 자격 증명 저장소와 상호작용합니다.
이 작업은 CredentialsContainer
인터페이스의 메서드를 통해 이루어지며,
Navigator
객체의 navigator.credentials 속성으로 노출됩니다.
partial interface Navigator { [SecureContext ,SameObject ]readonly attribute CredentialsContainer credentials ; };
credentials 속성은 반드시
활성 문서의 탐색 컨텍스트(browsing context)에 연결된
CredentialsContainer
객체를 반환해야 합니다.
참고: § 6.3 비보안 사이트에서 설명했듯이, 자격 증명 관리 API는 보안 컨텍스트(Secure Contexts)에서만 노출됩니다.
[Exposed =Window ,SecureContext ]interface {CredentialsContainer Promise <Credential ?>get (optional CredentialRequestOptions options = {});Promise <undefined >store (Credential credential );Promise <Credential ?>create (optional CredentialCreationOptions options = {});Promise <undefined >preventSilentAccess (); };dictionary {CredentialData required USVString ; };id
get(options)-
get()이 호출되면, 사용자 에이전트는 자격 증명(Request aCredential) 을options에 대해 실행한 결과를 반환해야 합니다.CredentialsContainer.get(options) 메서드 인자. 매개변수 타입 Nullable Optional 설명 optionsCredentialRequestOptions✘ ✔ 요청 범위를 제어하는 속성 집합 store(credential)-
store()이 호출되면, 사용자 에이전트는 자격 증명 저장(Store aCredential)을credential에 대해 실행한 결과를 반환해야 합니다.CredentialsContainer.store(credential) 메서드 인자. 매개변수 타입 Nullable Optional 설명 credentialCredential✘ ✘ 저장할 자격 증명 create(options)-
create()이 호출되면, 사용자 에이전트는 자격 증명 생성(Create aCredential)을options에 대해 실행한 결과를 반환해야 합니다.CredentialsContainer.create(options) 메서드 인자. 매개변수 타입 Nullable Optional 설명 optionsCredentialCreationOptions✘ ✔ Credential생성을 위한 옵션 preventSilentAccess()-
preventSilentAccess()이 호출되면, 사용자 에이전트는 Silent Access 방지를 현재 설정 객체(current settings object)에 대해 실행한 결과를 반환해야 합니다.참고: 이 기능은 사용자가 로그아웃했음을 origin에서 신호로 알리기 위한 것입니다. 즉, "로그아웃" 버튼 클릭 후 사이트가 세션 정보를 갱신하고,
navigator.credentials.preventSilentAccess()를 호출합니다. 이로 인해 silent access 방지 플래그가 설정되며, 다음 방문 시 자격 증명이 자동으로 페이지로 전달되지 않게 됩니다.참고: 이 함수는 이전에
requireUserMediation()라 불렸으며, 더 이상 권장되지 않습니다.
Navigator
객체(navigator)가 생성될 때, 사용자 에이전트는
navigator의 relevant Realm을 사용하여
새로운 CredentialsContainer
객체를 만들어 navigator와 연결해야 합니다.
2.3.1. CredentialRequestOptions
딕셔너리
Credential
을(를) get()
메서드로 조회하려면,
호출자는 CredentialRequestOptions
객체에 몇 가지 매개변수를 지정합니다.
참고: CredentialRequestOptions
사전(dictionary)은 확장 포인트(extension point)입니다.
만약 옵션이 필요한 새로운 종류의 자격 증명이 도입될 경우, 해당 사전 타입이 이 dictionary에 추가되어
요청(request) 시 전달될 수 있습니다. 자세한 사항은 § 8.2 확장 포인트를 참고하세요.
dictionary {CredentialRequestOptions CredentialMediationRequirement mediation = "optional";DOMString uiMode ;AbortSignal signal ; };
mediation, CredentialMediationRequirement 타입, 기본값은"optional"-
이 속성은 해당 자격 증명 요청의 mediation(중재) 조건을 지정합니다. 각 enum 값의 의미는 아래
CredentialMediationRequirement에서 설명합니다. 처리 세부사항은 § 2.5.1 자격 증명 요청(Request a Credential)에 정의되어 있습니다. uiMode, DOMString 타입-
이 속성은 사용자가 사용자 중재(user mediation)를 수행할 때 자격 증명 요청의 UI 모드를 지정합니다. 각 값의 의미는 아래
CredentialUiMode에서 설명되어 있습니다. 처리 세부사항은 § 2.5.1 자격 증명 요청(Request a Credential)에 정의되어 있습니다. signal, AbortSignal 타입-
이 속성을 통해 개발자는 진행 중인
get()작업을 중단(abort)할 수 있습니다. 중단된 작업은 일반적으로 작업이 끝난 뒤 abort를 받으면 정상적으로 완료되거나, 아니면 abort reason(중단 사유)과 함께 reject될 수 있습니다.
unmediated 멤버가 정의되어 있었습니다.
true로 설정 시 mediation
은
"silent"
가 되었고,
false일 때에는
mediation
이 "optional"가
되었습니다.
unmediated는 더 이상 권장되지 않으며,
새로운 코드는 mediation
속성을 사용해야 합니다.
CredentialCreationOptions
또는 CredentialRequestOptions
(options)에 대한
관련 자격 증명 인터페이스 객체(relevant
credential interface
objects)는 다음과 같이 수집된 interface objects 집합입니다:
참고: 이 알고리즘은 Credential Type Registry를 사용합니다.
-
settings를 현재 settings object로 둔다.
-
options의 각 optionKey → optionValue에 대해:
-
credentialInterfaceObject를 적절한 인터페이스 객체(Appropriate Interface Object)로 설정합니다. (settings의 global object에서, Options Member Identifier가 optionKey인 객체)
-
assert(확인): credentialInterfaceObject의
[[type]]슬롯 값이 Credential Type과 같아야 하며, 이 Credential Type의 Options Member Identifier가 optionKey이어야 한다. -
credentialInterfaceObject를 relevant interface objects에 추가한다.
-
-
relevant interface objects를 반환한다.
CredentialRequestOptions
(options)가
사전 매칭 가능(matchable a
priori)하려면
다음의 단계가 true를 반환해야 합니다:
-
options의 relevant credential interface objects의 각 interface에 대해:
-
만약 interface의
[[discovery]]슬롯 값이 "credential store"가 아니라면,false를 반환한다.
-
-
true를 반환한다.
참고: get(options)
실행 시,
주어진 CredentialRequestOptions
가 matchable a
priori일 때만,
사용자 중재(user mediation)
없이 자격 증명이 반환됩니다.
외부 서비스(OAuth 토큰, 보안 키 인증기 등)에서 탐색이 필요한 자격 증명 타입이
요청되는 경우,
선택적 아이덴티티 공급자, BTLE 장치 등 탐색 과정을 안내하기 위해
사용자 중재(user
mediation)가 요구됩니다.
2.3.2. 중재 요구사항
get(options)
또는 create(options)
를 통해 요청할 때,
개발자는 적절한 CredentialMediationRequirement
enum 값을 선택하여
사용자 중재 요구사항을 경우에 따라 지정할 수
있습니다.
참고: § 5 사용자 중재 절에서 전반적인 개념 및 각 origin 단위 요청 처리의 동작 영향에 관한 자세한 내용을 확인할 수 있습니다.
enum {CredentialMediationRequirement "silent" ,"optional" ,"conditional" ,"required" };
silent-
주어진 작업에 대해 사용자 중재가 억제(suppress)됩니다. 사용자의 개입 없이 작업을 수행할 수 있다면 그대로 진행합니다. 만약 사용자 개입이 필요하다면, 작업은 사용자를 개입시키지 않고
null을 반환합니다.참고: 해당 용례는 "이 사이트에 자동으로 로그인하기" 시나리오로, 사용자가 자동 로그인을 원하는 경우 자격 증명을 조용히 획득(사용자 팝업 없이)하되, 사용자의 명시적 로그인 동작 전까지 로그인 안내를 띄우지 않습니다.
optional-
사용자 중재 없이 자격 증명을 넘길 수 있을 때 그대로 넘깁니다. 만약 사용자 중재가 꼭 필요하다면, 사용자 에이전트가 사용자를 개입시킵니다.
참고: 이것이
get()의 기본 동작입니다. 사용자는 평소 로그인을 기대하는 케이스(로그인 버튼을 눌렀을 경우 등)에 해당하므로, 필요하다면 자격 증명 선택기가 보임에 놀라지 않습니다. conditional-
get()호출 시, 발견된 자격 증명은 사용자의 인증을 요청하는 origin 정보를 표시하는 비모달 다이얼로그로 제공합니다. 사용자가 다이얼로그 바깥을 클릭하면, 해당 다이얼로그는Promise를 resolve/reject하지 않으며 사용자가 볼 수 있는 에러 상태도 남기지 않고 닫힙니다. 사용자가 자격 증명을 선택하면 그 자격 증명이 호출자에게 반환됩니다. silent access 방지 플래그가 실제 값과 상관없이true로 간주되며, 해당conditional동작에서는 항상 사용자 중재가 동반됩니다.발견된 자격 증명이 없다면, 사용자 에이전트는 자격 증명 종류(예: 장치 삽입 등)에 따라 사용자의 추가 동작을 유도할 수 있습니다. 이 경우
get()은 해당 자격 증명이 없음을 바로null로 처리해 사이트에 노출해서는 안 됩니다.웹사이트는
conditional값을get()호출 시 주려면, 지목된 자격 증명 인터페이스마다isConditionalMediationAvailable()가true로 resolve되는Promise를 반환해야만 합니다.create()호출 시 사용자가 이미 자격 증명 생성을 허가했고, 최근 인증 또한 사용자 중재로 처리된 것으로 사용자 에이전트가 알고 있다면,create()호출 시 별도 prominent 모달 인터랙션 없이 resolve될 수 있습니다. 만약 사용자 중재 인증 이력이 없거나, 자격 증명 생성에 대한 동의가 없는 경우에는 "NotAllowedError"DOMException가 발생해야 합니다. required-
원(origin)에 대해 silent access 방지 플래그가 해제되어 있어도, 사용자 중재 없이 자격 증명이 반환되지 않습니다.
참고: 이 값은 재인증 또는 계정 전환을 보장하기 위한 용도입니다. 또한 이 설정은 특정 요청에만 적용되며, 해당 origin의 silent access 방지 플래그 에는 영향을 주지 않습니다. 플래그를 설정하려면
preventSilentAccess()를 호출해야 합니다.
2.3.3. UI 모드
get(options)
요청에서, 개발자는 적절한 CredentialUiMode
enum 값을 선택하여 원하는 사용자 중재
모드를 지정할 수 있습니다.
UI 모드 필드는 기본값이 없습니다. 미지정 상태라면,
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 메서드는
CredentialMediationRequirement
만으로 사용자 에이전트 동작을 결정해야 합니다.
참고: 이 필드는 호출자가
여러 종류의 사용자 중재 UI 방식 중 특정
방식을 구분해 지정할 수 있게 해줍니다.
UI 노출 여부는 해당 요청의 CredentialMediationRequirement
값에 따라 결정됩니다.
모든 CredentialUiMode
값들이 CredentialMediationRequirement
값들과 항상 호환되는 것은 아니며,
실제 동작은 각 자격 증명 타입이 지원하는
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
메서드의 정의에 좌우됩니다.
enum {CredentialUiMode "immediate" };
immediate-
get()호출시, 사용자 에이전트는 사용자에게 모달 자격 증명 선택 다이얼로그에 보여주거나, 또는 자격 증명을 제공하지 않고 즉시 작업을 완료합니다.이 값을 사용하면 간단한 로그인 UI를 사용자에게 표시하거나, 그렇지 않은 경우 사이트 자체 로그인 페이지를 띄우거나 비로그인 상태로 계속 진행할 수 있습니다.
자격 증명 선택 다이얼로그에 보여줄 자격 증명이 없으면, 사용자 중재는 예를 들어 자격 증명 입력 안내 없이 바로 건너뜁니다.
참고: 이 명세는
isConditionalMediationAvailable()와 같은immediate모드의 기능 지원 여부를 판별하는 정적 메서드를 제공하지 않습니다. 향후 이 mediation 모드가 다른 자격 증명 타입에도 확장될 경우,CredentialMediationRequirement와CredentialUiMode조합별로 어떤 타입이 지원되는지 알려줄 수 있는 검출 방식이 필요합니다.
2.3.3.1. 예시
get()
을 호출하고,
mediation
멤버를
"silent"
로 지정하면,
§ 5.2 사용자 중재 요구에 따라 중재 조건 해제(자동 로그인)에 동의한 사용자는
자동 로그인되고,
그렇지 않은 사용자는 맥락 없는 자격
증명 선택기가 갑자기 뜨지 않습니다.
window.addEventListener('load', async () => {
const credentials = await navigator.credentials.get({
...,
mediation: 'silent'
});
if (credentials) {
// Hooray! Let’s sign the user in using these credentials!
}
});
document.querySelector('#sign-in').addEventListener('click', async () => {
const credentials = await navigator.credentials.get({
...,
mediation: 'optional'
});
if (credentials) {
// Hooray! Let’s sign the user in using these credentials!
}
});
참고: MegaCorp, Inc.는
mediation
멤버를 아예 생략해도 됩니다.
"optional"
이 기본값이기 때문입니다.
get()
호출 시
mediation
멤버를
"required"
로 지정하면 됩니다.
참고: 브라우저 보안모델 또는 자격 증명 종류에 따라, 사용자에게 자격 증명 전달 전 마스터 비밀번호 입력, 지문 인식 등의 방식으로 본인 인증을 요구할 수 있습니다.
document.querySelector('#important-form').addEventListener('submit', async () => {
const credentials = await navigator.credentials.get({
...,
mediation: 'required'
});
if (credentials) {
// Verify that |credentials| enables access, and cancel the submission
// if it doesn’t.
} else {
e.preventDefault();
}
});
get()
을 호출할 때 mediation
멤버를
"required"
로 설정하여
"계정 추가" 버튼을 클릭할 때 자격 증명이
자동으로 반환되지 않게 할 수 있습니다:
document.querySelector('#switch-button').addEventListener('click', e => {
var c = await navigator.credentials.get({
...,
mediation: 'required'
});
if (c) {
// Sign the user in using |c|.
}
});
2.4. CredentialCreationOptions 딕셔너리
Credential
을(를) create()
를 통해 생성하려면,
호출자는 CredentialCreationOptions
객체에 몇 가지 매개변수를 지정합니다.
참고: CredentialCreationOptions
딕셔너리는 확장 포인트(extension point)입니다.
새로운 자격 증명 타입이 도입되면, 관련 옵션이 이 딕셔너리에 추가되어 생성 메서드에 전달할 수 있습니다.
자세한 내용은 § 8.2 확장 포인트와,
본 문서 예시:
§ 3.2 PasswordCredential 인터페이스, § 4.1 FederatedCredential 인터페이스를 참조하세요.
dictionary {CredentialCreationOptions CredentialMediationRequirement = "optional";mediation AbortSignal signal ; };
signal, AbortSignal 타입-
이 속성을 통해 개발자는 진행 중인
create()작업을 중단(abort)할 수 있습니다. 중단된 작업은 일반적으로 작업 완료 이후에 abort를 받았다면 정상적으로 완료되거나, 아니면 중단 사유(abort reason)와 함께 reject될 수 있습니다.
2.5. 알고리즘
2.5.1. Credential
요청
Credential 요청(Request a
Credential) 알고리즘은
CredentialRequestOptions
(options)을 받아,
자격 증명을 명확하게 획득할 수 있으면 해당 Credential로
resolve되는
Promise를
반환하고,
그렇지 않으면 null로 resolve합니다.
-
settings를 현재 설정 객체(current settings object)로 둔다.
-
assert: settings는 보안 컨텍스트(secure context)이다.
-
document를 settings의 관련 전역 객체(relevant global object)의 연결된 Document(associated Document)로 둔다.
-
만약 document가 완전히 활성화(fully active) 상태가 아니면 a promise rejected with "
InvalidStateError"DOMException을 반환한다. -
options.이 aborted라면, a promise rejected withsignaloptions.의 abort reason을 반환한다.signal -
interfaces를 options의 관련 자격 증명 인터페이스 객체(relevant credential interface objects)로 둔다.
-
만약 interfaces가 비어 있음(empty)이라면, a promise rejected with "
NotSupportedError"DOMException을 반환한다. -
각(for each) interface of interfaces에 대해:
-
만약 options.
mediation이conditional이고 interface가conditional사용자 중재(user mediation)를 지원하지 않으면, a promise rejected with "TypeError"DOMException을 반환한다. -
만약 options.
uiMode이immediate이고 interface가immediate사용자 중재(user mediation)를 지원하지 않으면, a promise rejected with "TypeError"DOMException을 반환한다. -
만약 settings의 active credential types에 interface의
[[type]]이 포함(contain)되어 있으면, a promise rejected with "NotAllowedError"DOMException을 반환한다. -
Append(추가) interface의
[[type]]을 settings의 active credential types에 추가한다.
-
-
origin을 settings의 origin으로 둔다.
-
sameOriginWithAncestors를 settings가 조상과 동일 출처(same-origin with its ancestors)인 경우에만
true, 그 외는false로 둔다. -
options의 관련 자격 증명 인터페이스 객체(relevant credential interface objects) 각 interface에 대해:
-
permission을 interface의
[[type]]Get Permissions Policy 결과로 둔다. -
permission이 null이면, continue.
-
만약 document가 allowed to use permission이 아니라면, a promise rejected with "
NotAllowedError"DOMException을 반환한다.
-
-
p를 새 promise로 둔다.
-
아래 단계를 병렬로(in parallel) 수행한다:
-
credentials를 자격 증명 저장소에서 Credential 수집의 결과로 origin, options, sameOriginWithAncestors 를 인자로 구한다.
-
credentials가 예외(exception)면 reject p에 credentials로 reject한다.
-
아래 모든 조건이 true이면 p를 credentials[0]으로 resolve하고 남은 단계를 skip한다:
-
credentials의 크기(size)가 1임
-
origin이 사용자 중재 필요하지 않음
-
options가 사전 매칭(matchable a priori)임.
-
options.
mediation이 "conditional"가 아님.
이 모델이 적절하지 않을 수 있음. 사이트가 username/password와 webauthn 타입 모두를 지원할 때 username/password를 쓰는 사용자가 계속 로그인 상태를 유지할 수 있도록 선택기(chooser) 강제 없이 처리할 수 있게 개선하면 좋을 수 있음.
-
-
만약 options의
mediation이 "silent"라면, resolve p에null로 resolve하고 남은 단계는 skip한다. -
result를 사용자에게 Credential 선택 요청(ask the user to choose a
Credential) 실행 결과로 options, credentials를 인자로 한다. -
result가 인터페이스 객체(interface object)라면:
-
result를 result의
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)실행 결과로 지정한다. (origin, options, sameOriginWithAncestors)이때 예외가 발생했다면:
-
e를 throw된 예외(exception)로 둔다.
-
작업 큐(queue a task)에, global의 DOM 조작 태스크 소스(DOM manipulation task source) 를 이용해 아래 하위 단계를 실행하도록 예약한다:
-
reject p에 e로 reject한다.
-
-
이 하위 단계를 종료한다.
-
-
-
assert: result는
null또는Credential이다. -
result가
Credential이면, resolve p를 result로 resolve한다. -
result가
null이고 options.mediation이conditional이 아니라면, resolve p를 result로 resolve한다.참고: options.
mediation이conditional이고 null 자격 증명 발견 시 promise p는 resolve되지 않는다.
-
-
-
interfaces의 각 interface에 대해:
-
Remove(제거) interface의
[[type]]을 settings의 active credential types에서 제거한다.
-
-
-
p를 반환한다.
2.5.2. 자격 증명 저장소에서 Credential 수집
origin (origin),
CredentialRequestOptions
(options), 그리고 호출 컨텍스트가
조상과 동일 출처(same-origin with its ancestors)
(sameOriginWithAncestors)일 때만
true인 불린 값이 주어졌을 때,
사용자 에이전트는
자격 증명 저장소에서
Credential 수집
작업을 수행할 수 있으며,
options의 필터에 부합하는 사용자 에이전트에 로컬 저장된
Credential
객체 집합을 반환한다. 해당하는
Credential
객체가 없다면, 반환 집합은 비어 있게 된다:
-
possible matches를 빈 집합으로 둔다.
-
options의 관련 자격 증명 인터페이스 객체의 각 interface에 대해:
-
r에 interface의
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)내부 메서드를 origin, options, sameOriginWithAncestors로 실행한 결과를 할당한다. 예외(exception)가 발생하면 해당 예외를 다시 throw한다. -
assert: r은(는) interface objects의 리스트여야 한다.
-
r의 각 c에 대해서:
-
append c를 possible matches에 추가한다.
-
-
-
possible matches를 반환한다.
2.5.3. Credential
저장
Credential 저장(Store a
Credential) 알고리즘은
Credential
(credential)을 받아,
자격 증명
저장소에 객체가 영구 저장(persist)되면
resolve되는 Promise를
반환한다.
-
settings를 현재 설정 객체(current settings object)로 둔다.
-
assert: settings는 보안 컨텍스트(secure context)이다.
-
만약 settings의 관련 전역 객체(relevant global object)의 연결된 Document(associated Document)가 완전히 활성화(fully active) 상태가 아니라면, a promise rejected with "
InvalidStateError"DOMException을 반환한다. -
sameOriginWithAncestors를 현재 설정 객체(current settings object)가 조상과 동일 출처(same-origin with its ancestors)일 경우
true, 그 외에는false로 둔다. -
p를 새 promise로 둔다.
-
만약 settings의 active credential types에 포함된 credential의
[[type]]이 있으면, a promise rejected with "NotAllowedError"DOMException을 반환한다. -
Append(추가) credential의
[[type]]을 settings의 active credential types에 추가한다. -
아래 단계를 병렬로(in parallel) 실행한다:
-
credential의 interface object의
[[Store]](credential, sameOriginWithAncestors)내부 메서드를 credential, sameOriginWithAncestors 인자로 실행한다.이때 예외(exception)가 발생했다면:
-
e를 throw된 예외(exception)로 둔다.
-
작업 큐(queue a task)를 global의 DOM 조작 태스크 소스(DOM manipulation task source) 로 실행하여 아래 하위 단계를 수행한다:
-
reject p에 e로 reject한다.
-
그 외의 경우 resolve p에
undefined로 resolve한다. -
-
-
-
Remove(제거) credential의
[[type]]을 settings의 active credential types에서 제거한다.
-
-
p를 반환한다.
2.5.4. Credential
생성
Credential 생성(Create a
Credential) 알고리즘은
CredentialCreationOptions
(options)을 받아,
주어진 옵션으로 자격 증명을 만들 수 있으면 Credential로
resolve되고,
만들 수 없으면 null로 resolve되는
Promise를
반환한다.
예외 상황에서는,
Promise가
적절한 예외로 reject될 수 있다:
-
settings를 현재 설정 객체(current settings object)로 둔다.
-
assert: settings는 보안 컨텍스트(secure context)이다.
-
global을 settings의 글로벌 객체(global object)로 둔다.
-
document를 관련 전역 객체(relevant global object)의 연결된 Document(associated Document)로 둔다.
-
document가 완전히 활성화(fully active) 상태가 아니면, a promise rejected with "
InvalidStateError"DOMException을 반환한다. -
조상과 동일 출처이면 sameOriginWithAncestors를
true, 아니면false로 한다. -
interfaces를 set(집합)으로서 options의 관련 자격 증명 인터페이스 객체를 담는다.
-
아래 조건 중 하나라도 true면 a promise rejected with
NotSupportedError를 반환한다:-
global에 연결된 Document(associated Document)가 없음.
-
interfaces의 크기(size)가 1보다 큼.
참고: 미래에는 이 제한을 완화하여 사용자 에이전트가 여러 자격 증명 타입 가운데 사용자가 하나를 고를 수 있도록 할 수 있음. 당장은 이 딕셔너리가 단일 entry만 갖게 하여 해당 use case는 보류.
-
-
interfaces의 각 interface마다:
-
permission을 interface의
[[type]]Create Permissions Policy 값으로 둔다. -
permission이 null이면 다음 interface로 continue.
-
document가 not allowed to use permission이면 a promise rejected with "
NotAllowedError"DOMException반환.
-
-
options.이 aborted라면, a promise rejected withsignaloptions.의 abort reason으로 반환.signal -
type을 interfaces[0]의
[[type]]으로 둔다. -
settings의 active credential types에 포함되어 있다면 a promise rejected with "
NotAllowedError"DOMException을 반환. -
Append(추가) type을 settings의 active credential types에 추가.
-
origin을 settings의 origin으로 둔다.
-
p를 새 promise로 둔다.
-
아래 단계를 병렬로(in parallel) 실행:
-
r을 interfaces[0]의
[[Create]](origin, options, sameOriginWithAncestors)내부 메서드 실행 결과로 둔다. (origin, options, sameOriginWithAncestors 인자 사용)이때 예외(exception)가 발생했다면:
-
e를 throw된 예외로 둔다.
-
작업 큐(queue a task)에서 global의 DOM 조작 태스크 소스(DOM manipulation task source) 로 아래 하위 단계를 실행:
-
reject p에 e로 reject.
-
-
하위 단계 종료.
-
-
r이
Credential또는null이면, resolve p를 r로 resolve하고 하위 단계 종료. -
assert: r은 § 2.2.1.4 [[Create]] 내부 메서드에 정의된 알고리즘임.
-
작업 큐(queue a task)에서 global의 DOM 조작 태스크 소스(DOM manipulation task source)로 아래 하위 단계를 실행:
-
Resolve p을 promise-calling r 결과(global 인자)로 resolve.
-
-
-
-
Remove(제거) type을 settings의 active credential types에서 제거.
-
-
p를 반환한다.
2.5.5. 암묵적 접근 방지
Silent Access 방지(Prevent Silent Access) 알고리즘은
environment settings object
(settings)을 받아,
prevent silent access 플래그가
자격 증명
저장소에 영구 저장되면 resolve되는
Promise
를 반환한다.
-
origin을 settings의 origin으로 둔다.
-
만약 settings의 관련 전역 객체(relevant global object)의 연결된 Document(associated Document)가 완전히 활성화(fully active) 상태가 아니라면, a promise rejected with "
InvalidStateError"DOMException을 반환한다. -
p를 새 promise로 둔다.
-
아래 단계를 병렬로(in parallel) 수행:
-
조용한 접근 방지 플래그(prevent silent access flag)를 자격 증명 저장소(credential store)에서 origin에 대해 설정한다.
-
resolve p를
undefined로 resolve한다.
-
-
p를 반환한다.
3. 비밀번호 자격 증명
좋든 나쁘든 많은 웹사이트가 사용자 이름/비밀번호 쌍에 인증 메커니즘을 의존합니다.
PasswordCredential
인터페이스는 이런 사용 사례를 지원하기 위한 자격 증명으로, 사용자 이름과 비밀번호를 저장하며,
사용자가 자격 증명 선택기에서
올바른 계정을 선택할 수 있도록 돕는 메타데이터도 함께 저장합니다.
3.1. 예시
3.1.1. 비밀번호 기반 로그인
navigator.credentials.get()
를 통해
사용자의 자격
증명 저장소에서
사용자명/비밀번호 쌍을 얻을 수 있습니다:
navigator.credentials .get({ 'password': true }) .then(credential => { if (!credential) { // 사용자가 이 사이트에 자격 증명이 없거나, // 공유를 거절함. 여기서 기본 로그인 폼으로 // 폴백되는 동작을 구현할 수 있습니다. return; } if (credential.type == 'password') { var form = new FormData(); form.append('username_field', credential.id); form.append('password_field', credential.password); var opt = { method: 'POST', body: form, credentials: 'include' // 쿠키도 함께 전송 }; fetch('https://example.com/loginEndpoint', opt) .then(function (response) { if (/* |response|가 로그인 성공이면 */) { // 이 credential이 실제로 사용되었음을 기록. 아래 참고. navigator.credentials.store(credential); // 사용자에게 로그인 성공 표시, 로그인된 UX로 전환 등 동작. // location.href = '/signed-in-experience'로 이동 등도 가능. } else { // 여기서 기본 로그인 폼 등으로 폴백 } }); } });
또는, 사이트는 자격 증명 데이터를 바로
form
에 복사하여
submit()
을 호출할 수도 있습니다:
navigator.credentials .get({ 'password': true }) .then(credential => { if (!credential) { return; // 위와 동일... } if (credential.type === 'password') { document.querySelector('input[name=username_field]').value = credential.id; document.querySelector('input[name=password_field]').value = credential.password; document.getElementById('myform').submit(); } });
전자의 방식이 훨씬 권장됩니다. 이 방식에서는 명시적으로 store()
를 호출해 자격 증명을 저장하기 때문입니다.
form
기반 방식은 폼 제출에 의존하고,
이는 브라우저 컨텍스트를 네비게이션하기 때문에,
로그인 성공 후 store()
를 반드시 호출하도록 보장하기 어렵습니다.
참고: 사용자 에이전트가 표시하는 자격 증명 선택기는
현재 origin에 실제로 저장되어 있지 않은 자격 증명도
사용자가 선택할 수 있게 할 수 있습니다.
예를 들어, https://www.example.com에 로그인할 때
https://m.example.com에 저장된 자격 증명을
제시하거나(§ 6.1 교차 도메인 자격 증명 접근 참고),
새 자격 증명을 즉석에서 만들 수도 있습니다.
개발자는 store()
를 항상 호출(심지어 get()
직후라도)
해서 이 불확실성을 처리할 수 있습니다:
자격 증명이 해당 origin에 저장되어 있지 않다면 사용자가 직접 저장 결정을 하도록 안내받게 되며,
이미 저장되어 있다면 별도 안내 없이 처리됩니다.
3.1.2. 로그인 후 확인
사용자가 성공적으로 로그인한 후 새로운 자격 증명 저장을 권장하려면, store()
에 전달하면 됩니다.
fetch()를 통해 sign-in endpoint에 자격 증명을 제출하여 로그인한 경우,
응답을 확인하여 로그인 성공 여부를 판단하고 사용자 에이전트에 알릴 수 있습니다. 다음과 같은 로그인 폼이 있을 때:
<form action="https://example.com/login" method="POST" id="theForm"> <label for="username">Username</label> <input type="text" id="username" name="username" autocomplete="username"> <label for="password">Password</label> <input type="password" id="password" name="password" autocomplete="current-password"> <input type="submit"> </form>
개발자는 다음과 같은 핸들러로 폼 제출을 처리할 수 있습니다:
document.querySelector('#theForm').addEventListener('submit', e => {
if (window.PasswordCredential) {
e.preventDefault();
// "submit" 이벤트가 발생한 PasswordCredential을 HTMLFormElement에서 생성:
// "username" 및 "current-password" autocomplete 필드 값을 자동으로 읽어들입니다:
var c = new PasswordCredential(e.target);
// 폼의 action URL로 새 자격 증명을 FormData로 전송. 응답이 성공적이면 사용자 에이전트에 알려, 사용자가 비밀번호를 저장할 수 있도록 합니다:
var opt = {
method: 'POST',
body: new FormData(e.target),
credentials: 'include' // 쿠키 전송.
};
fetch(e.target.action, opt).then(r => {
if (/* |r|이 "성공적인" Response인 경우 */)
navigator.credentials.store(c);
});
}
});
3.1.3. 비밀번호 변경
동일한 저장 메커니즘은 "비밀번호 변경"에도 아무런 수정 없이 재사용할 수 있습니다. 사용자가 자격 증명을 변경하면, 웹사이트는 사용자가 새 자격 증명으로 성공적으로 로그인했음을 사용자 에이전트에 알릴 수 있습니다. 그러면 사용자 에이전트는 저장된 자격 증명을 업데이트할 수 있습니다:
store()
를 새 정보와 함께 호출하여 사용자의 자격 증명을 업데이트할 수 있습니다.
다음과 같은 비밀번호 변경 폼이 있을 때:
<form action="https://example.com/changePassword" method="POST" id="theForm"> <input type="hidden" name="username" autocomplete="username" value="user"> <label for="password">New Password</label> <input type="password" id="password" name="password" autocomplete="new-password"> <input type="submit"> </form>
개발자는 다음과 같이 폼 제출을 처리할 수 있습니다:
document.querySelector('#theForm').addEventListener('submit', e => {
if (window.PasswordCredential) {
e.preventDefault();
// "submit" 이벤트가 발생한 PasswordCredential을 HTMLFormElement에서 생성:
// "username" 및 "new-password" autocomplete 필드 값을 자동으로 읽어들입니다:
var c = new PasswordCredential(e.target);
// 폼의 action URL로 새 자격 증명을 FormData로 전송. 응답이 성공적이면 사용자 에이전트에 알려, 사용자가 비밀번호를 저장할 수 있도록 합니다:
var opt = {
method: 'POST',
body: new FormData(e.target),
credentials: 'include' // 쿠키 전송.
};
fetch(e.target.action, opt).then(r => {
if (/* |r|이 "성공적인" Response인 경우 */)
navigator.credentials.store(c);
});
}
});
3.2.
PasswordCredential 인터페이스
[Exposed =Window ,SecureContext ]interface :PasswordCredential Credential {constructor (HTMLFormElement );form constructor (PasswordCredentialData );data readonly attribute USVString password ; };PasswordCredential includes CredentialUserData ;partial dictionary CredentialRequestOptions {boolean =password false ; };
password, 타입 USVString, 읽기 전용-
이 속성은 자격 증명의 비밀번호를 나타냅니다.
[[type]]-
PasswordCredential인터페이스 객체는[[type]]라는 내부 슬롯을 가지며, 그 값은 "password"입니다. [[discovery]]-
PasswordCredential인터페이스 객체는[[discovery]]라는 내부 슬롯을 가지며, 그 값은 "credential store"입니다. PasswordCredential(form)-
이 생성자는
HTMLFormElement(form)을 받고 다음 단계를 실행합니다:-
origin을 현재 settings object의 origin으로 한다.
-
r을 HTMLFormElement에서
PasswordCredential생성의 결과로, form과 origin을 인자로 실행한다. -
그렇지 않으면 r을 반환.
-
PasswordCredential(data)-
이 생성자는
PasswordCredentialData(data)를 받고 다음 단계를 실행합니다:-
r을 PasswordCredentialData에서
PasswordCredential생성 결과로, data에 대해 실행. -
그렇지 않으면 r을 반환.
-
PasswordCredential
객체는 PasswordCredentialData
딕셔너리를 명시적으로 전달하거나,
HTMLFormElement의
제출 가능한 요소를 기반으로 navigator.credentials.create()로
생성할 수 있습니다.
dictionary :PasswordCredentialData CredentialData {USVString ;name USVString ;iconURL required USVString ;origin required USVString ; };password typedef (PasswordCredentialData or HTMLFormElement );PasswordCredentialInit partial dictionary CredentialCreationOptions {PasswordCredentialInit ; };password
PasswordCredential
객체는 origin에
바인딩됩니다.
PasswordCredential의
인터페이스 객체는 Credential의
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
구현을 상속하며,
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors),
[[Create]](origin, options, sameOriginWithAncestors),
[[Store]](credential, sameOriginWithAncestors)는
자체적으로 구현합니다.
3.3. 알고리즘
3.3.1.
PasswordCredential의
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
는 origin (origin), CredentialRequestOptions
(options),
그리고 호출 컨텍스트가 조상과 동일 출처
(sameOriginWithAncestors)일 경우에만 true인 불리언 값을 인자로 호출됩니다.
알고리즘은 자격 증명 저장소에서
Credential
객체 집합을 반환합니다. 일치하는 Credential
객체가 없다면, 반환 집합은 비어 있습니다.
sameOriginWithAncestors가 true가 아니면 이 알고리즘은 NotAllowedError를
throw합니다.
-
sameOriginWithAncestors가
false이면 "NotAllowedError"DOMException을 throw한다.참고: 이 제한은 § 6.4 출처 혼동(Origin Confusion) 문제 보완을 목적합니다.
-
만약 options["
password"] 가true가 아니면 빈 집합을 반환한다. -
자격 증명 저장소에서 아래와 같이 필터링하여 자격 증명 목록을 반환한다:
-
자격 증명이
PasswordCredential임 -
자격 증명의
[[origin]]이 origin과 동일 출처인 경우
-
3.3.2. PasswordCredential의
[[Create]](origin, options, sameOriginWithAncestors)
[[Create]](origin, options, sameOriginWithAncestors)
는 origin (origin),
CredentialCreationOptions
(options), 그리고 호출 컨텍스트가
조상과 동일 출처
(sameOriginWithAncestors)인 경우에만 true인 불리언을 인자로 받습니다.
알고리즘은 생성 가능하다면 PasswordCredential
을 반환하고,
아니라면 null을 반환합니다.
CredentialCreationOptions
딕셔너리에는 반드시 password 멤버가 있어야 하며,
이 값은 HTMLFormElement
또는 PasswordCredentialData여야
합니다.
만약 해당 멤버의 값을 사용해
PasswordCredential
을 만들 수 없다면,
이 알고리즘은 TypeError
예외(exception)를 throw합니다.
-
assert: options["
password"] 존재해야 하며, sameOriginWithAncestors는 사용되지 않음. -
options["
password"] 이HTMLFormElement이라면, HTMLFormElement에서PasswordCredential생성을 options["password"]와 origin을 인자로 실행하여 나온 결과 값을 반환. 예외 발생 시 그대로 rethrow. -
options["
password"] 가PasswordCredentialData라면, PasswordCredentialData에서PasswordCredential생성을 options["password"]에 대해 실행하여, 결과 값을 반환한다. 예외 발생 시 그대로 rethrow.
3.3.3.
PasswordCredential의 [[Store]](credential, sameOriginWithAncestors)
[[Store]](credential, sameOriginWithAncestors)
는
PasswordCredential
(credential)과,
호출 컨텍스트가 조상과 동일 출처
(sameOriginWithAncestors)일 때만 true인 불리언을 인자로 받습니다.
알고리즘은 credential이 자격 증명 저장소에 영구 저장(persist)되면
undefined를 반환합니다.
sameOriginWithAncestors가 true가 아니면, 이 알고리즘은 NotAllowedError를 반환합니다.
-
만약 sameOriginWithAncestors가
false이면, 사용자 에이전트의 자격 증명 저장소를 변경하지 않고 "NotAllowedError"DOMException을 throw한다.참고: 이 제한은 § 6.4 출처 혼동(Origin Confusion) 문제 보완을 목적합니다.
-
만약 사용자 에이전트의 자격 증명 저장소에
PasswordCredential(stored)가 존재하고, 이idattribute가 credential의id와 같으며,[[origin]]슬롯 역시 credential의[[origin]]과 동일 출처라면:-
사용자가 자격 증명 업데이트 동의를 한 경우(사용자 중재에서 논의한 대로):
그 외 사용자 저장 동의가 있을 경우(사용자 중재 참고):
-
자격 증명 저장소에 아래 속성으로
PasswordCredential을(를) 저장한다:id-
credential의
id name,-
credential의
name iconURL-
credential의
iconURL [[origin]]-
credential의
[[origin]] password-
credential의
password
-
3.3.4. HTMLFormElement에서 PasswordCredential 생성
HTMLFormElement에서
PasswordCredential 생성 알고리즘은 HTMLFormElement
(form)과 origin (origin)이 주어지면 다음 단계를 실행합니다.
참고: § 3.1.2 로그인 후 확인 및 § 3.1.3 비밀번호 변경에서 사용 예시를 제공합니다.
-
data를 새로운
PasswordCredentialData딕셔너리로 한다. -
data의
origin멤버 값을 origin의 값으로 설정한다. -
formData를
FormData생성자로 form에 대해 실행한 결과로 한다. -
elements를 form의 제출 가능한 요소 중 form owner가 form인 것의 리스트로, 트리 순서로 정렬한다.
-
newPasswordObserved를
false로 한다. -
elements의 각 field에 대해 아래 단계를 실행:
-
field에
autocomplete속성이 없으면, 다음 field로 건너뛴다. -
name을 field의
name속성 값으로 한다. -
formData의
has()메서드를 name에 대해 실행했을 때false면, 다음 field로 건너뛴다. -
field의
autocomplete값에 하나 이상의 자동완성 상세 토큰(tokens)이 포함된다면:-
tokens의 각 token에 대해:
-
token이 아래 문자열 중 하나와 ASCII 대소문자 구분 없이 일치한다면, 해당 절차를 실행:
- "
new-password" -
data의
password멤버 값을 formData의get()메서드를 name에 대해 실행한 결과로 설정하고, newPasswordObserved를true로 설정한다. - "
current-password" -
newPasswordObserved가
false이면, data의password멤버 값을 formData의get()메서드를 name에 대해 실행한 결과로 설정.참고: newPasswordObserved가
false인 경우,new-password필드가current-password필드보다 우선함을 의미합니다. - "
photo" -
data의
iconURL멤버 값을 formData의get()메서드를 name에 대해 실행한 결과로 설정. - "
name"- "
nickname" - "
- "
username"
- "
-
-
-
-
c를 PasswordCredentialData에서
PasswordCredential생성을 data에 대해 실행한 결과로 한다. 예외가 발생하면 재throw한다. -
Assert: c는
PasswordCredential이다. -
c를 반환한다.
3.3.5. PasswordCredentialData에서 PasswordCredential 생성
주어진 PasswordCredentialData (data)로부터
PasswordCredential
생성
알고리즘을 수행하려면 아래 단계를 따르십시오.
-
c를 새
PasswordCredential객체로 둡니다. -
c의 프로퍼티를 다음과 같이 설정합니다:
-
c를 반환합니다.
3.3.6.
PasswordCredential에 대한 CredentialRequestOptions 매칭
CredentialRequestOptions
(options)이 주어졌을 때, 다음 알고리즘은
PasswordCredential
이(가) get()
요청에 대해 응답으로 제공되어야 하면 "Matches"를,
그렇지 않으면 "Does Not Match"를 반환한다.
-
options에
password멤버가 있고, 그 값이true라면 "Matches"를 반환한다. -
"
Does Not Match"를 반환한다.
4. 연합 자격 증명
4.1.
FederatedCredential 인터페이스
[Exposed =Window ,SecureContext ]interface :FederatedCredential Credential {constructor (FederatedCredentialInit );data readonly attribute USVString provider ;readonly attribute DOMString ?protocol ; };FederatedCredential includes CredentialUserData ;dictionary {FederatedCredentialRequestOptions sequence <USVString >;providers sequence <DOMString >; };protocols partial dictionary CredentialRequestOptions {FederatedCredentialRequestOptions ; };federated
provider, 타입 USVString, 읽기 전용-
자격 증명의 페더레이티드(연합) 아이덴티티 제공자. 허용된 형식의 세부사항은 § 4.1.1 제공자 식별 참고.
protocol, 타입 DOMString, 읽기 전용, nullable-
자격 증명 페더레이티드 아이덴티티 제공자의 프로토콜(예: "
openidconnect"). 값이null이면 프로토콜은provider에서 추론할 수 있습니다. [[type]]-
FederatedCredentialinterface object에는[[type]]이라는 내부 슬롯이 있으며, 값은 "federated"입니다. [[discovery]]-
FederatedCredentialinterface object에는[[discovery]]라는 내부 슬롯이 있고, 그 값은 "credential store"입니다. FederatedCredential(data)-
이 생성자는
FederatedCredentialInit(data)를 받고, 아래 단계를 수행합니다:-
r을 FederatedCredentialInit에서
FederatedCredential생성 결과로 두고, 예외가 발생하면 다시 throw 합니다. -
r을 반환합니다.
-
FederatedCredential
객체는 FederatedCredentialInit
딕셔너리를
navigator.credentials.create()
에 전달함으로써 생성할 수 있습니다.
dictionary :FederatedCredentialInit CredentialData {USVString ;name USVString ;iconURL required USVString ;origin required USVString ;provider DOMString ; };protocol partial dictionary CredentialCreationOptions {FederatedCredentialInit ; };federated
FederatedCredential
객체는 origin
bound입니다.
FederatedCredential의
interface object는 Credential의
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)
구현을 상속하며,
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors),
[[Create]](origin, options, sameOriginWithAncestors),
[[Store]](credential, sameOriginWithAncestors)
를 자체적으로 구현합니다.
참고: 나중에 사용자 에이전트가 사용자를 대신해 인증 토큰을 획득하도록 지원할 경우,
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 구현에 의해 가능합니다.
4.1.1. 제공자 식별
모든 사이트는 특정 연합 신원 제공자를 참조할 때 동일한 식별자를 사용해야 합니다. 예를 들어, Facebook Login은 "Facebook", "Facebook Login", "FB", "FBL", "Facebook.com" 등 여러 이름이 아닌, 모두가 사용할 수 있는 표준 식별자를 가져야 합니다. 일관된 식별은 사용자 에이전트가 더 유용하게 동작할 수 있게 해줍니다.
일관성을 위해, 이 문서에서 정의된 API(예: FederatedCredentialRequestOptions의
providers
배열 또는 FederatedCredential의
provider
속성)에 전달되는 federation은 제공자가 로그인에 사용하는 origin의 ASCII serialization으로 식별되어야 합니다.
즉, Facebook은 https://www.facebook.com으로, Google은 https://accounts.google.com으로
표시됩니다.
이 origin의 serialization에는 마지막 U+002F SOLIDUS("/")가 포함되지
않지만,
사용자 에이전트는 이를 묵인해야 합니다: https://accounts.google.com/은 분명히
https://accounts.google.com과 동일합니다.
4.2. 알고리즘
4.2.1.
FederatedCredential의
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
는 origin (origin), CredentialRequestOptions
(options),
그리고 호출 컨텍스트가 조상과 동일 출처
(sameOriginWithAncestors)일 때만 true가 되는 불린 값을 인자로 호출됩니다.
이 알고리즘은 자격 증명 저장소에서
Credential
객체 집합을 반환합니다. 일치하는 Credential
객체가 없다면 반환 집합은 비어 있습니다.
-
sameOriginWithAncestors가
false이면 "NotAllowedError"DOMException을 throw 한다.참고: 이 제한은 § 6.4 출처 혼동 문제 해소를 목적으로 합니다.
-
options["
federated"] 값이true가 아니면 빈 집합을 반환한다. -
자격 증명 저장소에서 아래 조건으로 자격 증명 목록을 반환한다:
4.2.2. FederatedCredential의
[[Create]](origin, options, sameOriginWithAncestors)
[[Create]](origin, options, sameOriginWithAncestors)
는 origin(origin), CredentialCreationOptions
(options), 그리고 상위와 동일 origin(sameOriginWithAncestors)일
때 true인 boolean 값을 인자로 호출됩니다.
알고리즘은 생성 가능한 경우 FederatedCredential을
반환하며,
그렇지 않으면 null을 반환하거나, 예외 상황에서는 exception을
던집니다:
-
단언: options["
federated"] 존재함, 그리고 sameOriginWithAncestors는 사용되지 않음. -
FederatedCredentialInit로부터
FederatedCredential생성을 실행한 결과를 반환합니다. 예외가 발생하면 그 예외를 다시 던집니다.
4.2.3.
FederatedCredential의 [[Store]](credential, sameOriginWithAncestors)
[[Store]](credential, sameOriginWithAncestors)
는 FederatedCredential
(credential)과, 상위와 동일 origin(sameOriginWithAncestors)일
때 true인 boolean 값을 인자로 호출됩니다.
알고리즘은 credential이 credential store에 저장된 후 undefined를 반환합니다.
알고리즘은 sameOriginWithAncestors가 true가 아니면 NotAllowedError를 반환합니다.
-
"
NotAllowedError"DOMException을 던지고, 사용자 에이전트의 credential store는 변경하지 않습니다. (sameOriginWithAncestors가false인 경우)참고: 이 제한은 § 6.4 Origin 혼동에서 제기된 문제를 해결하기 위함입니다.
-
사용자 에이전트의 credential store에
FederatedCredential이 있고, 그id속성이 credential의id와 같고,[[origin]]슬롯이 credential의[[origin]]과 동일 origin이고,provider가 credential의provider와 같으면 반환합니다. -
사용자가 자격 증명 저장 권한을 부여하면(user mediation 정의 참고), 다음 속성으로 credential store에
FederatedCredential을 저장합니다:
4.2.4.
FederatedCredentialInit로부터 FederatedCredential 생성
FederatedCredentialInit로부터
FederatedCredential 생성을 위해,
FederatedCredentialInit
(init)을 인자로 다음 단계를 수행합니다.
5. 사용자 중재
API를 통해 웹에 자격 증명 정보를 노출하는 것은 사용자 프라이버시에 여러 잠재적인 영향을 줄 수 있습니다. 그러므로 사용자 에이전트는 사용자가 무슨 일이 일어나고 있는지, 그리고 누구와 자격 증명이 공유되고 있는지 명확히 이해할 수 있도록 여러 상황에서 반드시 사용자를 개입시켜야(MUST) 합니다.
특정 동작이 사용자의 명시적 동의 후에 이루어지는 경우, 우리는 이를 사용자 중재(user mediated) 라고 부릅니다. 예를 들면 사용자가 자격 증명 선택기 인터페이스에서 직접 상호작용하여 동의를 표현할 수 있습니다. 일반적으로 사용자 중재 동작은 사용자가 UI를 접하고 그에 대한 결정을 내리도록 요구하는 과정을 포함합니다.
동작이 명시적 사용자 동의 없이 조용히(silently) 수행되는 경우, 이를 비중재(unmediated)라고 합니다. 예를 들어, 사용자가 브라우저 설정을 통해 특정 origin에 지속적으로 자격 증명 접근을 허용했다면, 자격 증명 제공 시 별도의 결정 요청 UI 없이 전달될 수 있습니다.
여기서는 모든 자격 증명 타입에 공통되는 일부 요구 사항을 명확히 기술합니다. 단, 사용자 에이전트가 사용자 보호 측면에서 다양한 재량을 가질 수 있음을 참고하세요 (사용자 에이전트는 사용자를 돕는 특권적 위치에 있음). 또한, 특정 자격 증명 타입은 여기서 설명하는 일반 요구 사항보다 더 엄격한 개별 요건을 가질 수 있습니다.
5.1. 자격 증명 저장 및 갱신
자격 증명 정보는 민감한 데이터이며, 사용자는 이 정보의 저장에 대한 통제권을 반드시(MUST) 가져야 합니다. 예를 들어, 의도치 않은 자격 증명 저장은 특정 디바이스의 사용자의 로컬 프로필을 온라인 페르소나와 예기치 않게 연결할 수 있습니다. 이런 불의의 위험을 줄이기 위해:
-
자격 증명 정보는 사용자 중재 없이 저장되거나 갱신되어서는 안 됩니다(SHOULD NOT). 예를 들어, 사용자 에이전트는
store()를 호출할 때마다 "이 자격 증명을 저장하시겠습니까?" 다이얼로그 박스를 표시할 수 있습니다.사용자가 "항상 비밀번호 저장" 옵션 등 영구 동의 권한을 직접 설정할 경우, 사용자 동의가 부여된 것으로 간주할 수 있습니다(MAY). (다만, 사용자 에이전트는 더 제한적인 범위로 — 예를 들면 "항상 _생성된_ 비밀번호 저장", 또는 "이 사이트에만 항상 비밀번호 저장" — 접근하는 것이 권장됨.)
-
사용자 에이전트는 자격 증명이 저장될 때 사용자가 알 수 있도록 알림을 제공해야 합니다(SHOULD). 예를 들어, 주소창에 아이콘을 표시하거나 이와 유사한 위치에 노출할 수 있습니다.
-
사용자 에이전트는 사용자가 저장된 자격 증명을 수동으로 삭제할 수 있도록 반드시(MUST) 허용해야 합니다. 이 기능은 설정 페이지나 위에서 말한 알림과의 상호작용 등으로 구현될 수 있습니다.
5.2. 사용자 중재 요구
기본적으로 사용자 중재가
모든 origin에 대해 요구됩니다.
이는 자격
증명 저장소에서 관련
silent access 방지 플래그
가 true로 설정되어 있기 때문입니다.
사용자는 어떤 origin에 대해 자격 증명
영구 접근 권한(예: "이 사이트에 계속 로그인" 옵션)을
부여할 수 있으며, 이 경우 플래그가
false로 전환됩니다.
이런 경우 사용자는 항상 해당 사이트에 로그인되어
있게 되므로, 사용성과 편의성 측면에서는
바람직하지만(다만, 예를 들어 에이전트가
이 플래그 상태를 기기 간 동기화한다면
사용자 입장에서 당황스러운 결과를
초래할 수도 있습니다).
이런 의도치 않은 상황의 위험을 줄이기 위하여:
-
사용자 에이전트는 특정 origin 또는 모든 origin에 대해 사용자 중재를 반드시(MUST) 요구할 수 있어야 합니다. 이 기능은 모든 origin의 silent access 방지 플래그 를
false로 덮는(override) 글로벌 토글로 구현할 수도 있고, 특정 origin 또는 특정 자격 증명별 세밀한 설정으로 제공될 수도 있습니다. -
사용자 에이전트는 origin의 silent access 방지 플래그 를 사용자 중재 없이
false로 설정해서는 안 됩니다(MUST NOT). 예를 들어 자격 증명 선택기 (§ 5.3 자격 증명 선택 참고)에 체크박스를 추가해 사용자가 해당 자격 증명을 origin에 대해 중재 없이 쓸 수 있도록 선택하게 하거나, 에이전트의 자격 증명 관리자 온보딩 과정에서 초기 설정을 물어보는 방식일 수 있습니다. -
사용자 에이전트는 자격 증명이 origin에 제공될 때 반드시(MUST) 사용자에게 알림을 제공해야 합니다. 예를 들어 주소창 아이콘 표시 등 다양한 형태로 구현할 수 있습니다.
-
사용자가 특정 origin에 대한 브라우징 데이터(쿠키, localStorage 등)를 삭제할 경우, 에이전트는 해당 origin의 silent access 방지 플래그 를
true로 반드시(MUST) 설정해야 합니다.
5.3. 자격 증명 선택
사용자 중재(user mediation)가
요구되는 origin에서
get()
호출에 응답할 때,
사용자 에이전트는 자격 증명 정보 공유에
대한 사용자 동의를 반드시(MUST) 요청해야 합니다.
이는 사용자에게 해당 사이트에서 사용할 수 있는
자격 증명 목록을 보여주고, 사용자가 제공할
자격 증명을 선택하거나 요청 자체를
중단하도록 할 수 있는
자격 증명 선택기(credential chooser) 형태의
UI로 구현되어야 합니다(SHOULD).
선택기의 사용자 인터페이스는 웹사이트가 흉내낼 수 없는 구별 가능한 방식으로 반드시 구현되어야(SHOULD) 합니다. 예를 들어 진짜 선택기는 사용자 에이전트의 UI 일부와 겹친다든지 위조할 수 없는 방식이 될 수 있습니다.
선택기의 사용자 인터페이스에는 자격 증명을 요청하는 origin이 반드시(MUST) 표시되어야 합니다.
선택기 UI에는
해당 origin과 연관된 모든
Credential
객체가 포함되어야 합니다(SHOULD).
사용자 에이전트는 선택기의 효용을 높이기
위해 각 Credential
객체에
본 문서에서 규정하지 않은 추가 정보를
내부적으로 연결시킬 수 있습니다(MAY).
예를 들어, 파비콘 이미지를 표시해
아이덴티티 제공자를 쉽게 구분하게 할 수
있습니다. 단, 이러한 부가 정보는
반드시 웹에 직접 노출되어서는 안 됩니다(MUST).
선택기의 구체적인 동작 방식은 이 문서에서 정의하지 않으며, 사용자 에이전트는 인증 옵션에 대한 이해를 돕고 자격 증명 선택 과정을 안내하는 UI 실험을 권장합니다. 단, 선택기에 대한 인터페이스는 다음과 같습니다:
CredentialRequestOptions
(options)와
자격 증명
저장소에서
얻은 Credential
집합(locally discovered
credentials)을 받아
사용자에게 Credential 선택 요청(ask the
user to choose a
Credential)을 할 수 있습니다.
이 알고리즘은 사용자가 사이트에 자격 증명을
제공하지 않기로 하면 null을,
사용자가 구체적 자격 증명을 선택하면
해당 Credential
객체를,
자격 증명 타입을 선택하면
Credential
interface object를
반환합니다.

만약 options가 사전 매칭(matchable a priori)이 아니라면, 선택기 인터페이스는 명시적 자격 증명 리스트에 포함되지 않는 관련 자격 증명 인터페이스 객체 도 표시할 수 있습니다. 예를 들어, 사이트가 webauthn 타입 인증기를 받아들인다면 "보안 키"가 적절한 아이콘과 함께 선택기 목록에 들어갈 수도 있습니다.
또한 경우에 따라 사용자 에이전트가 선택기 UI를 완전히 생략할 수도 있습니다. 예를 들어 관련 자격 증명 인터페이스 객체 가 오직 사용자의 개입을 필요로 하는 타입뿐일 경우, 에이전트는 선택기 없이 해당 인터페이스를 직접 반환하여, 사용자 동의는 그 내부 중재 절차에 맡길 수 있습니다.
6. 보안 고려사항
다음 섹션은 다양한 보안 및 프라이버시 고려사항에 대한 가이드라인을 제시합니다. 개별 자격 증명 타입은 이 가이드라인보다 더 엄격하거나 느슨한 버전을 적용할 수 있습니다.
6.1. 도메인 간 자격 증명 접근
자격 증명은 민감한 정보이므로, 사용자 에이전트는
언제 자격 증명을 웹사이트에 안전하게
공유할 수 있는지 결정할 때 신중을
기해야 합니다. 가장 안전한 방법은
자격 증명을 저장된 정확한 origin에서만
공유하도록 제한하는 것이지만,
웹 환경에는 너무 제한적일 수 있습니다.
예를 들어 example.com과
admin.example.com 등
하위 도메인으로 기능을 분리하는
사이트의 경우가 있습니다.
사용자 불편과 자격 증명 보호 사이의 타협안으로, 사용자 에이전트는 다음과 같이 동작해야 합니다:
-
보안 수준이 강등되는 scheme끼리(origin) 자격 증명을 공유해서는 안 됩니다(MUST NOT). 즉,
http://example.com/에 저장된 자격 증명을https://example.com/에서 사용할 수 있게 하는 것은 개발자가 보안 전송으로 마이그레이션할 수 있도록 허용할 수 있지만, 그 반대는 위험합니다. -
자격 증명의 유효 범위를 판단하기 위해 Public Suffix List [PSL]를 사용할 수 있습니다(MAY). 즉, 자격 증명의 등록 도메인(registerable domain)을
[[origin]]및get()이 호출되는 origin에 대해 비교해서 범위를 결정할 수 있습니다. 예를 들어https://admin.example.com/과https://example.com/에 저장된 자격 증명을https://www.example.com/에서 get() 호출 시 사용자에게 제공할 수 있으며, 그 반대 역시 허용될 수 있습니다. -
자격 증명의 origin이 호출 origin과 완전히 일치하지 않는 경우, 사용자 중재 없이
get()에 자격 증명을 바로 제공해서는 안 됩니다(MUST NOT). 즉,Credential객체가https://example.com용일 때,https://www.example.com에 바로 반환해서는 안 되고 반드시 선택기(chooser) UI를 통해 사용자가 직접 선택할 수 있어야 제공됩니다.
6.2. 자격 증명 누출
개발자들은 교차 사이트 스크립팅 공격이 사용자의 계정에 대한 지속적인 접근으로 이어지는 위험을 완화하기 위해, 데이터를 전송할 수 있는 엔드포인트를 제한하는 적절한 콘텐츠 보안 정책(Content Security Policy, [CSP])을 설정하는 등의 예방 조치를 취하는 것이 바람직합니다. 특히, 개발자들은 페이지의 정책에 다음 지시어들이 명시적으로 또는 암묵적으로 설정되어 있는지 확인해야 합니다:
-
script-src와 object-src 모두 페이지에서 스크립트 실행을 제한하여 교차 사이트 스크립팅 공격이 처음부터 성공할 가능성을 줄여줍니다. 사이트에서
form요소를 사용한다면, form-action 지시어도 설정해야 합니다. -
connect-src는
fetch()를 통해 데이터를 제출할 수 있는 origin을 제한합니다(이를 통해 자격 증명이evil.com등으로 유출되는 위험을 줄일 수 있습니다). -
child-src는 페이지에 포함될 수 있는 중첩 브라우징 컨텍스트를 제한하여 악의적인
postMessage()대상이 주입되는 것을 더욱 어렵게 만듭니다. [HTML]
개발자는 입력 및 출력을 반드시 적절히 이스케이프 처리하고, 위험을 더욱 줄이기 위해 Subresource Integrity [SRI]와 같은 추가적인 방어 계층도 고려해야 합니다.
특정 자격 증명 타입을 정의할 때, 관련 자격 증명 타입은 자격 증명 데이터가 네트워크로 전송되는 방식에 충분히 주의를 기울여야 합니다. 예를 들어, 전송 메커니즘을 동일 origin의 엔드포인트로만 제한하도록 정의하는 것이 합리적일 수 있습니다.
6.3. 안전하지 않은 사이트
사용자 에이전트는 보안 컨텍스트가 아닌 환경에는 여기에서 정의된 API를 노출해서는 안 됩니다. 사용자 에이전트는 사용자 자격 증명을 저장하고 신뢰할 수 없는 URL에서 로그인 양식을 자동으로 채우는 기능을 구현할 수 있지만, 그러한 사이트는 자격 증명 관리자와 직접적으로 상호작용할 수 있는 신뢰할 수 있는 환경이 아니며, 해당 사이트는 보안 컨텍스트에 저장된 자격 증명에 접근할 수 없어야 합니다.
6.4. Origin 혼동
프레임된 페이지가 여기서 정의된 API에 접근할 수 있다면, 사용자가 최상위 탐색 컨텍스트가 아닌 다른 origin에 대한 자격 증명 접근을 허용하도록 혼란스럽게 만들 가능성이 있습니다. 사용자가 합리적으로 이해할 수 있는 유일한 보안 origin은 최상위 탐색 컨텍스트입니다.
이 문서는 Credential Management API를 해당 컨텍스트에 노출합니다. 일부 자격 증명 타입은 사용자 에이전트가 UI에 충분한 고려와 맥락을 담을 경우 쉽게 제공할 수 있을 것으로 보입니다.
그러나 특정 자격 증명 타입은 그러한 컨텍스트에서 위험 없이 노출하기 어렵습니다. 해당 자격 증명 타입은 [[Create]](origin, options, sameOriginWithAncestors),
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors),
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors),
그리고 [[Store]](credential, sameOriginWithAncestors)
메서드에서 적절한 검사를 통해 제한됩니다.
예를 들어 PasswordCredential의
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)
메서드는 Worker나
비-최상위 탐색 컨텍스트에서 호출되는 경우 즉시 빈 집합을 반환합니다.
6.5. 로그아웃
§ 5.2 사용자 중재 요구에서 논의된 바와 같이, 사용자가 자동 로그인 선택을 한 경우, 사용자 에이전트는
origin이 자격 증명을 요청할 때마다 이를 제공하게 됩니다. 웹사이트는 CredentialsContainer의
preventSilentAccess()
메서드를 호출하여 이 동작을 억제할 수 있으며, 이는 해당 origin의 자동 로그인을 비활성화합니다.
사용자 에이전트는 웹사이트가 올바르게 동작할 것이라 기대합니다. 부주의하거나 악의적인 웹사이트는 이 메서드를 호출하지 않아, 사용자 에이전트가 사용자의 의도와 달리 계속 자격 증명을 제공할 수 있습니다. 이는 사용자가 "로그아웃"을 클릭해도 사이트가 사용자 자격 증명을 지우지 않는 기존 상황보다 약간 더 나쁜 상황입니다. 사용자 에이전트가 인증에 관여하게 되기 때문입니다.
사용자는 반드시 이 동작을 제어할 수 있어야 합니다. § 5.2 사용자 중재 요구에서 언급한 바와 같이,
origin의 쿠키를 삭제하면 해당 origin의 prevent silent access flag가 자격 증명
저장소에서 true로 초기화됩니다. 또한, 사용자 에이전트는 특정 origin에 대한 자동 로그인을 비활성화할 수 있는 UI 옵션도 제공해야 합니다.
예를 들어, 자격 증명이 origin에 제공되었을 때 표시되는 알림에 연동될 수 있습니다.
7. 프라이버시 고려사항
7.1. 타이밍 공격
사용자가 특정 origin에 자격 증명이 없는 경우 get()
호출은 매우 빠르게 완료됩니다. 악의적인 웹사이트는 자격 증명이 없는 사용자를, 자격 증명이 있지만 공유하지 않기로 선택한 사용자를 구별할 수 있습니다.
사용자 에이전트는 또한 자격 증명 요청을 속도 제한(rate-limit)해야 합니다. 짧은 시간에 여러 번 자격 증명 요청을 하는 것은 거의 확실히 악용에 해당합니다.
7.2. 선택기 정보 누출
만약 사용자 에이전트의 자격 증명
선택기가 origin이 제공한 이미지를 표시한다면
(예: Credential
에 사이트의 파비콘이 표시되는 경우),
이러한 이미지 요청은 반드시(MUST NOT)
선택기 표시 동작과 직접 연결되어서는 안 됩니다.
이렇게 하면 선택기 사용 정보가 누출되는 것을 방지할 수 있습니다.
한가지 방법은 Credential
저장 또는 갱신 시점에 이미지를 백그라운드로 받아
Credential
생명주기 동안 캐시하는 것입니다.
이러한 이미지는 반드시 다음 조건으로 페치되어야 합니다(MUST):
credentials mode는 "omit",
service-workers mode는 "none",
client는 null,
initiator는 빈 문자열,
destination은 "subresource".
또한, 사용자 에이전트가 사용자가 자격 증명에 연결된 이름이나 아이콘을 변경할 수 있게 하는 경우, 데이터의 이런 변경 내용들은 웹사이트에 노출되어서는 안 됩니다(SHOULD NOT). (사용자가 하나의 origin에 대해 "내 가짜 계정" 과 "내 진짜 계정"처럼 두 자격 증명에 이름을 지정하는 경우 등을 고려)
7.3. 로컬 저장 데이터
이 API는 origin이 사용자의 프로필과 함께 데이터를 영구적으로 저장할 수 있는 기능을 제공합니다. 대부분의 사용자 에이전트는 자격 증명 데이터를 "브라우징 데이터"(쿠키 등)와 다르게 처리하기 때문에, 사용자가 쿠키를 지울 때 모든 흔적이 삭제된다고 생각할 수 있지만 실제로는 자격 증명 데이터가 남아 있을 수 있습니다.
사용자 에이전트는 origin에 대해 자격 증명 데이터가 저장되어 있음을 명확하게 보여주는 UI를 제공해야 하며, 사용자가 더 이상 해당 데이터를 유지하고 싶지 않을 때 쉽게 삭제할 수 있도록 해야 합니다.
8. 구현 관련 고려사항
이 섹션은 규범적이지 않습니다.
8.1. 웹사이트 개발자
이 API가 언제, 어떻게 사용되어야
하는지에 대해,
특히 mediation와
관련하여 의견을 추가해야 합니다.
[w3c/webappsec Issue #290]
fetch()에서 FormData
body를 이용해 자격 증명을 제출할 때의 인코딩 제약 조건을 설명해야 합니다.
특정 자격 증명 타입에 대해 기능 감지를 수행할 때,
개발자는 관련 Credential
특수화가 존재하는지를
반드시 확인하는 것이 바람직합니다. 단순히 navigator.credentials의 존재만 확인해서는 충분하지
않습니다. 후자는 API 자체의 존재만 검증할 뿐, 해당 사이트에 필요한 특정 유형의 자격 증명이
지원되는지 보장하지 않습니다. 예를 들어 사이트에서 비밀번호가 필요하다면,
if (window.PasswordCredential)로 확인하는 것이 가장 효과적인 방법입니다.
8.2. 확장 포인트
이 문서는 확장 가능한, 고수준의 범용 API를 제공합니다. 이를 통해 각각의 인증 요구사항에 맞춘 자격 증명 타입을 추가 확장할 수 있도록 설계되었습니다. 이런 확장은 비교적 단순하게 이뤄질 수 있습니다:
-
아래처럼
Credential을 상속하는 새 인터페이스를 정의합니다: -
[[Create]](origin, options, sameOriginWithAncestors),[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors),[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors),[[Store]](credential, sameOriginWithAncestors)메서드를ExampleCredential의 interface object에 정의합니다.[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)는 영구적으로 유효한 자격 증명에 적합하며, 자격 증명 저장소 에서 그냥 복사해 반환하면 됩니다. 반면[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)는 다시 생성해야 하는 자격 증명에 적합하며, 자격 증명 소스로부터 매번 생성해야 합니다.예를 들어,
PublicKeyCredential의[[Create]](origin, options, sameOriginWithAncestors)및[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)처럼 장시간 실행되는 작업은options.signal를 이용해 개발자가 작업을 취소(abort)할 수 있도록 구현하는 것이 바람직합니다. 더 자세한 내용은 DOM § 3.3 AbortController와 AbortSignal 활용 을 참고하세요.ExampleCredential의[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors)내부 메서드는 origin (origin)과 CredentialRequestOptions (options), 그리고 조상과 동일 출처일 경우에true인 불린 을 인자로 호출됩니다. 이 알고리즘은 지정 옵션과 일치하는Credential객체 집합을 반환합니다. 일치하는Credential객체가 없으면, 빈 집합을 반환합니다.-
assert:
options[example] 존재. -
options[example]이 참(truthy)이 아니면 빈 집합 반환. -
각 credential in 자격 증명 저장소(credential store):
-
...
-
-
-
ExampleCredentialinterface object의[[type]]슬롯 값을 정의합니다: -
ExampleCredentialinterface object의[[discovery]]슬롯 값을 정의합니다: -
CredentialRequestOptions을 확장하여 신규 자격 증명 타입이get()요청에 알맞게 대응하도록 필요한 옵션을 추가합니다: -
CredentialCreationOptions을 확장하여 신규 자격 증명 타입이Credential객체를create()요청에 알맞게 생성할 수 있도록 데이터를 추가합니다: -
새 자격 증명 타입이
conditional사용자 중재를 지원한다면,ExampleCredential/isConditionalMediationAvailable()가 a promise resolved withtrue를 반환하도록 정의합니다. -
§ 2.1.2.1 등록 항목 요건 및 수정 방법에 따라 새로운 "example" 자격 증명 타입과 아래 항목들을 Credential Type Registry에 추가합니다:
-
CredentialCreationOptions'와CredentialRequestOptions'의 옵션 멤버 식별자 (이 경우 "example"), 그리고 -
적합한 인터페이스 객체 식별자(identifier) (이 경우
ExampleCredential).
참고: 자격 증명 타입의 옵션 딕셔너리의 옵션 멤버 식별자는
CredentialCreationOptions와CredentialRequestOptions양쪽 모두에서 동일해야 하며,Credentialinterface object의[[type]]슬롯의 값과도 일치해야 합니다. -
신규 확장에서 한 번에 여러
Credential
객체(예: 다요소 인증 등)를 반환해야 할 필요가 있을 수 있습니다.
이런 경우에는 getAll() 메서드를
CredentialsContainer
에 추가하여
sequence<Credential>을 반환하게 하고
여러 타입 자격 증명 요청에 handling 할
메커니즘을 별도로 정의할 수도 있습니다.
이와 같은 확장안을 만드실 때는 public-webappsec@로 문의와 리뷰를 권장합니다.
8.3. 브라우저 확장 프로그램
이상적으로, 확장 시스템을 구현한 사용자 에이전트는 써드파티가 이러한 API 엔드포인트에 연결하여 써드파티 자격 증명 관리 소프트웨어의 동작을 향상시킬 수 있도록 허용해야 하며, 이는 사용자 에이전트가 명령형(imperative) 방식으로 자체 동작을 개선하는 것과 동일합니다.
이는 사용자 에이전트가 중재하는 복잡한 새로운 API 구현부터, 확장 프로그램이 자체 목적에 맞게 get()
및 store()
엔드포인트를 덮어써서 사용할 수 있도록 하는 것까지 다양할 수 있습니다.
9. 향후 작업
이 섹션은 규범적이지 않습니다.
여기에서 정의된 API는 사용자 에이전트의 자격 증명 관리자를 웹에 노출하는 데 최소한의 기능만을 제공하며, 웹이 자격 증명 관리자가 연합 신원 제공자(federated identity provider)가 사용 중임을 이해하는 데 도움을 줄 수 있게 합니다. 다음 단계는 [WEB-LOGIN]과 같은 문서(그리고 어느 정도는 Mozilla의 BrowserID [BROWSERID])에서 제시된 방향을 따르는 것이 될 것입니다.
사용자 에이전트는 사용자, 신원 제공자, 그리고 웹사이트 간의 관계를 효과적으로 중재할 수 있는 독특한 위치에 있습니다. 사용자 에이전트가 일반적인 인증 흐름에 수반되는 위험과 혼란을 일부 제거할 수 있다면, 사용자는 오늘날보다 훨씬 더 나은 위치에 있게 될 것입니다.
이 정보를 노출하는 자연스러운 방법은 FederatedCredential
인터페이스에 인증 토큰과 같은 속성을 추가하거나, 제공자가 지원하는 인증 타입을 선언하는 속성을 가진 매니페스트 형식을 추가하는 것일 수 있습니다.
여기서 설명하는 API는 사용자 상호작용이 필요한 사용 사례(아마도 자격 증명을 요청한 웹사이트가 아닌 다른 웹사이트와 함께)까지 지원할 수 있도록 충분히 확장 가능하게 설계되었습니다.
Promise 기반 시스템이 여러 탐색 컨텍스트(예: idp.com에서 중재된 활동이 rp.com에 반환된 Promise를 해결하는 경우)나
디바이스 및 사용자 에이전트 간(예: [WEBAUTHN])의 일부
상호작용을 지원할 수 있을 만큼 충분히 확장 가능하기를 바랍니다. 이러한 흐름을 위해 API를 처음부터 다시 설계하지 않아도 되기를 희망합니다.
작은 한 걸음씩.