FedCM (제휴 사용자 인증 정보 관리)은 제휴 ID 서비스 (예: '다음으로 로그인')에 대한 개인 정보 보호 접근 방식으로, 사용자가 ID 서비스 또는 사이트에 개인 정보를 공유하지 않고도 사이트에 로그인할 수 있습니다.
FedCM 구현에는 IdP (ID 공급자)와 RP (신뢰 당사자) 모두에 관한 여러 핵심 단계가 포함됩니다.
IdPs는 FedCM을 구현하기 위해 다음 단계를 완료해야 합니다.
- well-known 파일을 만듭니다.
- 구성 파일을 만듭니다.
- 다음 엔드포인트를 만듭니다.
- 계정 엔드포인트
- ID 어설션 엔드포인트
- [선택사항] 엔드포인트 연결 해제
- [선택사항] 클라이언트 메타데이터 엔드포인트
- 로그인 엔드포인트
- 브라우저에 사용자 로그인 상태를 알립니다.
RP는 사이트에서 FedCM을 사용 설정하려면 다음 단계를 완료해야 합니다.
- RP 사이트에서 FedCM 엔드포인트가 허용되는지 확인합니다.
- FedCM JavaScript API를 사용하여 사용자 인증을 시작합니다.
- IdP에 메타데이터 (예: 개인정보처리방침 및 서비스 약관 URL)를 제공합니다.
- [선택사항] UX 모드를 선택하거나, 로그인 또는 도메인 힌트를 제공하거나, 맞춤 매개변수를 전달하거나, 특정 사용자 정보를 요청하거나, 맞춤 오류 메시지를 제공하거나, 사용자를 다시 인증하는 방법을 선택하여 사용자 환경을 맞춤설정합니다.
FedCM을 IdP로 구현
IdP 측에서 FedCM을 구현하는 단계에 대해 자세히 알아보세요.
잘 알려진 파일 만들기
추적 광고주가 API를 악용하지 못하도록 하려면 IdP의 eTLD+1에 있는 /.well-known/web-identity
에서 잘 알려진 파일을 제공해야 합니다.
잘 알려진 파일에는 다음 속성이 포함될 수 있습니다.
속성 | 필수 | 설명 |
---|---|---|
provider_urls
|
필수 | IdP 구성 파일 경로 배열입니다. accounts_endpoint 및 login_url 가 지정된 경우 무시되지만 여전히 필요합니다. |
accounts_endpoint
|
권장, login_url 필요 |
계정 엔드포인트의 URL입니다. 이렇게 하면 각 구성 파일이 동일한 login_url 및 accounts_endpoint URL을 사용하는 한 여러 구성을 지원할 수 있습니다.참고: 이 매개변수는 Chrome 132부터 지원됩니다. |
login_url
|
권장, accounts_endpoint 필요 |
사용자가 IdP에 로그인할 수 있는 로그인 페이지 URL입니다. 이렇게 하면 각 구성 파일에서 동일한 login_url 및 accounts_endpoint 를 사용하는 한 여러 구성을 지원할 수 있습니다.참고: 이 매개변수는 Chrome 132 이상에서 지원됩니다. |
예를 들어 IdP 엔드포인트가 https://accounts.idp.example/
아래에서 제공되는 경우 https://idp.example/.well-known/web-identity
에서 IdP 구성 파일과 함께 잘 알려진 파일을 제공해야 합니다. 다음은 잘 알려진 파일 콘텐츠의 예입니다.
{
"provider_urls": ["https://accounts.idp.example/config.json"]
}
IdP는 well-known 파일에 accounts_endpoint
및 login_url
를 지정하여 IdP의 여러 구성 파일을 수용할 수 있습니다.
이 기능은 다음과 같은 경우에 유용할 수 있습니다.
- IdP는 여러 가지 테스트 및 프로덕션 구성을 지원해야 합니다.
- IdP는 리전별로 서로 다른 구성 (예:
eu-idp.example
및us-idp.example
)을 지원해야 합니다.
여러 구성을 지원하려면 (예: 테스트 환경과 프로덕션 환경을 구분) IdP에서 accounts_endpoint
및 login_url
를 지정해야 합니다.
{
// This property is required, but will be ignored when IdP supports
// multiple configs (when `accounts_endpoint` and `login_url` are
// specified), as long as `accounts_endpoint` and `login_url` in
// that config file match those in the well-known file.
"provider_urls": [ "https://idp.example/fedcm.json" ],
// Specify accounts_endpoint and login_url properties to support
// multiple config files.
// Note: The accounts_endpoint and login_url must be identical
// across all config files. Otherwise,
// the configurations won't be supported.
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
IdP 구성 파일 및 엔드포인트 만들기
IdP 구성 파일은 브라우저에 필요한 엔드포인트 목록을 제공합니다. IdP는 하나 이상의 구성 파일과 필요한 엔드포인트 및 URL을 호스팅해야 합니다. 모든 JSON 응답은 application/json
콘텐츠 유형으로 제공되어야 합니다.
구성 파일의 URL은 RP에서 실행된 navigator.credentials.get()
호출에 제공된 값에 따라 결정됩니다.
const credential = await navigator.credentials.get({
identity: {
context: 'signup',
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
nonce: '******'
}]
}
});
const { token } = credential;
RP는 구성 파일의 URL을 FedCM API 호출에 전달하여 사용자가 로그인할 수 있도록 합니다.
// Executed on RP's side:
const credential = await navigator.credentials.get({
identity: {
context: 'signup',
providers: [{
// To allow users to sign in with an IdP using FedCM, RP specifies the IdP's config file URL:
configURL: 'https://accounts.idp.example/fedcm.json',
clientId: '********',
});
const { token } = credential;
브라우저는 Origin
헤더 또는 Referer
헤더가 없는 GET
요청으로 구성 파일을 가져옵니다. 요청에 쿠키가 없으며 리디렉션을 따르지 않습니다.
이렇게 하면 IdP가 요청한 사용자와 연결하려는 RP를 알 수 없게 됩니다. 예를 들면 다음과 같습니다.
GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity
IdP는 JSON으로 응답하는 구성 엔드포인트를 구현해야 합니다. JSON에는 다음 속성이 포함됩니다.
속성 | 설명 |
---|---|
accounts_endpoint (필수) |
계정 엔드포인트의 URL입니다. |
accounts.include (선택사항)
|
이 구성 파일을 사용할 때 반환해야 하는 계정을 결정하는 맞춤 계정 라벨 문자열입니다(예: "accounts": {"include": "developer"} ).
IdP는 다음과 같이 맞춤 계정 라벨을 구현할 수 있습니다.
예를 들어 IdP는 "accounts": {"include": "developer"} 가 지정된 "https://idp.example/developer-config.json" 구성 파일을 구현합니다. IdP는 계정 엔드포인트에서 labels 매개변수를 사용하여 일부 계정을 "developer" 라벨로 표시합니다. RP가 "https://idp.example/developer-config.json" 구성 파일이 지정된 navigator.credentials.get() 를 호출하면 "developer" 라벨이 있는 계정만 반환됩니다.
|
client_metadata_endpoint (선택사항) |
클라이언트 메타데이터 엔드포인트의 URL입니다. |
id_assertion_endpoint (필수) |
ID 어설션 엔드포인트의 URL입니다. |
disconnect (선택사항) |
연결 해제 엔드포인트의 URL입니다. |
login_url (필수) |
사용자가 IdP에 로그인할 수 있는 로그인 페이지 URL입니다. |
branding (선택사항) |
다양한 브랜딩 옵션을 포함하는 객체입니다. |
branding.background_color (선택사항) |
'계속...' 버튼의 배경 색상을 설정하는 브랜딩 옵션입니다. 관련 CSS 문법(예: hex-color , hsl() , rgb() , named-color )을 사용합니다. |
branding.color (선택사항) |
'계속...' 버튼의 텍스트 색상을 설정하는 브랜딩 옵션입니다. 관련 CSS 문법(예: hex-color , hsl() , rgb() , named-color )을 사용합니다. |
branding.icons (선택사항) |
아이콘 객체의 배열입니다. 이러한 아이콘은 로그인 대화상자에 표시됩니다. 아이콘 객체에는 두 가지 매개변수가 있습니다.
|
modes |
FedCM UI가 다양한 모드로 표시되는 방식에 관한 사양을 포함하는 객체입니다.
|
modes.active
|
특정 모드에서 FedCM 동작을 맞춤설정할 수 있는 속성이 포함된 객체입니다. modes.active 와 modes.passive 모두 다음 매개변수를 포함할 수 있습니다.
참고: 다른 계정 사용 기능과 활성 모드는 Chrome 132부터 지원됩니다. |
modes.passive
|
다음은 IdP의 응답 본문 예입니다.
{
"accounts_endpoint": "/accounts.example",
"client_metadata_endpoint": "/client_metadata.example",
"id_assertion_endpoint": "/assertion.example",
"disconnect_endpoint": "/disconnect.example",
"login_url": "/login",
// When RPs use this config file, only those accounts will be
//returned that include `developer` label in the accounts endpoint.
"accounts": {"include": "developer"},
"modes": {
"active": {
"supports_use_other_account": true,
}
},
"branding": {
"background_color": "green",
"color": "#FFEEAA",
"icons": [{
"url": "https://idp.example/icon.ico",
"size": 25
}]
}
}
브라우저가 구성 파일을 가져오면 후속 요청을 IdP 엔드포인트로 전송합니다.
다른 계정 사용
IdP에서 여러 계정을 지원하거나 기존 계정을 대체하는 경우 사용자는 현재 로그인한 계정과 다른 계정으로 전환할 수 있습니다.
사용자가 다른 계정을 선택할 수 있도록 하려면 IdP가 구성 파일에서 이 기능을 지정해야 합니다.
{
"accounts_endpoint" : "/accounts.example",
"modes": {
"active": {
// Allow the user to choose other account (false by default)
"supports_use_other_account": true
}
// "passive" mode can be configured separately
}
}
계정 엔드포인트
IdP의 계정 엔드포인트는 사용자가 IdP에 로그인한 계정 목록을 반환합니다. IdP에서 여러 계정을 지원하는 경우 이 엔드포인트는 로그인된 모든 계정을 반환합니다.
브라우저가 SameSite=None
와 함께 쿠키가 포함된 GET
요청을 전송하지만 client_id
매개변수, Origin
헤더 또는 Referer
헤더는 포함하지 않습니다. 이렇게 하면 IdP가 사용자가 로그인하려는 RP를 알 수 없게 됩니다. 예를 들면 다음과 같습니다.
GET /accounts.example HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
서버는 요청을 수신하면 다음을 실행해야 합니다.
- 요청에
Sec-Fetch-Dest: webidentity
HTTP 헤더가 포함되어 있는지 확인합니다. - 세션 쿠키를 이미 로그인한 계정의 ID와 일치시킵니다.
- 계정 목록으로 응답합니다.
브라우저는 다음 속성이 있는 계정 정보 배열이 포함된 accounts
속성이 포함된 JSON 응답을 예상합니다.
속성 | 설명 |
---|---|
id (필수) |
사용자의 고유 ID입니다. |
name (필수) |
사용자의 이름 및 성입니다. |
email (필수) |
사용자의 이메일 주소입니다. |
given_name (선택사항) |
사용자의 이름입니다. |
picture (선택사항) |
사용자 아바타 이미지의 URL입니다. |
approved_clients (선택사항) |
사용자가 등록한 RP 클라이언트 ID 배열입니다. |
login_hints (선택사항) |
IdP에서 계정을 지정하기 위해 지원하는 모든 필터 유형의 배열입니다. RP는 loginHint 속성으로 navigator.credentials.get() 를 호출하여 지정된 계정을 선택적으로 표시할 수 있습니다. |
domain_hints (선택사항) |
계정이 연결된 모든 도메인의 배열입니다. RP는 domainHint 속성으로 navigator.credentials.get() 를 호출하여 계정을 필터링할 수 있습니다. |
labels (선택사항)
|
계정이 연결된 맞춤 계정 라벨 문자열 배열입니다. IdP는 다음과 같이 맞춤 계정 라벨을 구현할 수 있습니다.
예를 들어 IdP는 "accounts": {"include": "developer"} 가 지정된 https://idp.example/developer-config.json 구성 파일을 구현합니다. IdP는 계정 엔드포인트에서 labels 매개변수를 사용하여 일부 계정을 "developer" 라벨로 표시합니다. RP가 https://idp.example/developer-config.json 구성 파일이 지정된 navigator.credentials.get() 를 호출하면 "developer" 라벨이 있는 계정만 반환됩니다.맞춤 계정 라벨은 IdP 서버에서 완전히 유지 관리되고 RP는 사용할 구성 파일만 지정한다는 점에서 로그인 힌트 및 도메인 힌트와 다릅니다. |
응답 본문 예시:
{
"accounts": [{
"id": "1234",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
// Ids of those RPs where this account can be used
"approved_clients": ["123", "456", "789"],
// This account has 'login_hints`. When an RP calls `navigator.credentials.get()`
// with a `loginHint` value specified, for example, `exampleHint`, only those
// accounts will be shown to the user whose 'login_hints' array contains the `exampleHint`.
"login_hints": ["demo1", "exampleHint"],
// This account is labelled. IdP can implement a specific config file for a
// label, for example, `https://idp.example/developer-config.json`. Like that
// RPs can filter out accounts by calling `navigator.credentials.get()` with
// `https://idp.example/developer-config.json` config file.
"labels": ["hr", "developer"]
}, {
"id": "5678",
"given_name": "Johnny",
"name": "Johnny",
"email": "johnny@idp.example",
"picture": "https://idp.example/profile/456",
"approved_clients": ["abc", "def", "ghi"],
"login_hints": ["demo2"],
"domain_hints": ["@domain.example"]
}]
}
사용자가 로그인하지 않은 경우 HTTP 401
(승인되지 않음)으로 응답합니다.
반환된 계정 목록은 브라우저에서 사용하며 RP에서는 사용할 수 없습니다.
ID 어설션 엔드포인트
IdP의 ID 어설션 엔드포인트는 로그인한 사용자의 어설션을 반환합니다.
사용자가 navigator.credentials.get()
호출을 사용하여 RP 웹사이트에 로그인하면 브라우저는 SameSite=None
쿠키와 콘텐츠 유형 application/x-www-form-urlencoded
가 포함된 POST
요청을 다음 정보와 함께 이 엔드포인트로 전송합니다.
속성 | 설명 |
---|---|
client_id (필수) |
RP의 클라이언트 식별자입니다. |
account_id (필수) |
로그인하는 사용자의 고유 ID입니다. |
disclosure_text_shown |
불리언이 아닌 "true" 또는 "false" 문자열을 반환합니다. 다음의 경우 결과는 "false" 입니다.
|
is_auto_selected |
RP에서 자동 재인증이 실행되면 is_auto_selected 은 "true" 을 나타냅니다. 그 외의 경우에는 "false" 입니다. 이렇게 하면 더 많은 보안 관련 기능을 지원하는 데 도움이 됩니다. 예를 들어 인증 시 명시적인 사용자 중재가 필요한 더 높은 보안 등급을 선호하는 사용자도 있습니다. IdP가 이러한 미디에이션 없이 토큰 요청을 수신하면 요청을 다르게 처리할 수 있습니다. 예를 들어 RP가 mediation: required 를 사용하여 FedCM API를 다시 호출할 수 있도록 오류 코드를 반환합니다. |
fields (선택사항)
|
RP가 IdP와 공유해야 하는 사용자 정보 ('이름', '이메일', '사진')를 지정하는 문자열 배열입니다. browser는 다음 예와 같이 POST 요청에 지정된 필드를 나열하는 fields , disclosure_text_shown , disclosure_shown_for 를 전송합니다.참고: Fields 매개변수는 Chrome 132부터 지원됩니다. |
params (선택사항)
|
맞춤 키-값 매개변수를 추가로 지정할 수 있는 유효한 JSON 객체입니다. 예를 들면 다음과 같습니다.
params 값이 JSON으로 직렬화된 후 퍼센트로 인코딩됩니다.참고: Parameters API는 Chrome 132 이상에서 지원됩니다. |
HTTP 헤더 예:
POST /assertion.example HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
// disclosure_text_shown is set to 'false', as the 'name' field value is missing in 'fields' array
// params value is serialized to JSON and then percent-encoded.
account_id=123&client_id=client1234&disclosure_text_shown=false&is_auto_selected=true¶ms=%22%7B%5C%22nonce%5C%22%3A%5C%22nonce-value%5C%22%7D%22.%0D%0A4&disclosure_text_shown=true&fields=email,picture&disclosure_shown_for=email,picture
서버는 요청을 수신하면 다음을 실행해야 합니다.
- CORS (교차 출처 리소스 공유)를 사용하여 요청에 응답합니다.
- 요청에
Sec-Fetch-Dest: webidentity
HTTP 헤더가 포함되어 있는지 확인합니다. Origin
헤더를client_id
에 의해 결정된 RP 출처와 일치시킵니다. 일치하지 않으면 거부합니다.account_id
를 이미 로그인한 계정의 ID와 일치시킵니다. 일치하지 않으면 거부합니다.- 토큰으로 응답합니다. 요청이 거부되면 오류 응답으로 응답합니다.
IdP는 토큰을 발급하는 방법을 결정할 수 있습니다. 일반적으로 RP가 토큰의 진위를 확인할 수 있도록 계정 ID, 클라이언트 ID, 발급자 출처, nonce와 같은 정보로 서명됩니다.
브라우저는 다음 속성이 포함된 JSON 응답을 예상합니다.
속성 | 설명 |
---|---|
token |
토큰은 인증에 관한 클레임을 포함하는 문자열입니다. |
continue_on |
다단계 로그인 흐름을 사용 설정하는 리디렉션 URL입니다. |
반환된 토큰은 RP가 인증을 검증할 수 있도록 브라우저에서 RP에 전달됩니다.
{
// IdP can respond with a token to authenticate the user
"token": "***********"
}
계속 진행 기능
IdP는 ID 어설션 엔드포인트 응답에 리디렉션 URL을 제공하여 다단계 로그인 흐름을 사용 설정할 수 있습니다. 이는 IdP에서 추가 정보나 권한을 요청해야 하는 경우에 유용합니다. 예를 들면 다음과 같습니다.
- 사용자의 서버 측 리소스에 액세스할 수 있는 권한입니다.
- 연락처 정보가 최신 상태인지 확인
- 자녀 보호 기능
ID 어설션 엔드포인트는 ID 어설션 엔드포인트의 절대 경로 또는 상대 경로가 포함된 continue_on
속성을 반환할 수 있습니다.
{
// In the id_assertion_endpoint, instead of returning a typical
// "token" response, the IdP decides that it needs the user to
// continue on a popup window:
"continue_on": "https://idp.example/continue_on_url"
}
응답에 continue_on
매개변수가 포함된 경우 새 팝업 창이 열리고 사용자가 지정된 경로로 이동합니다.
사용자가 continue_on
페이지와 상호작용한 후에는 IdP가 원래 navigator.credentials.get()
호출의 약속을 확인할 수 있도록 토큰을 인수로 전달하여 IdentityProvider.resolve()
를 호출해야 합니다.
document.getElementById('example-button').addEventListener('click', async () => {
let accessToken = await fetch('/generate_access_token.cgi');
// Closes the window and resolves the promise (that is still hanging
// in the relying party's renderer) with the value that is passed.
IdentityProvider.resolve(accessToken);
});
그러면 브라우저에서 팝업을 자동으로 닫고 API 호출자에게 토큰을 반환합니다. 일회성 IdentityProvider.resolve()
호출은 상위 창 (RP)과 팝업 창 (IdP)이 통신하는 유일한 방법입니다.
사용자가 요청을 거부하면 IdP는 IdentityProvider.close()
를 호출하여 창을 닫을 수 있습니다.
IdentityProvider.close();
Continuation API가 작동하려면 명시적인 사용자 상호작용 (클릭)이 필요합니다. Continuation API가 다양한 미디에이션 모드에서 작동하는 방식은 다음과 같습니다.
- 패시브 모드:
mediation: 'optional'
(기본값): Continuation API는 페이지 또는 FedCM UI의 버튼을 클릭하는 등의 사용자 동작으로만 작동합니다. 사용자 동작 없이 자동 재인증이 트리거되면 팝업 창이 열리지 않고 약속이 거부됩니다.mediation: 'required'
: 항상 사용자에게 상호작용을 요청하므로 Continuation API가 항상 작동합니다.
- 활성 모드:
- 사용자 활성화는 항상 필요합니다. Continuation API는 호환됩니다.
어떤 이유로든 사용자가 팝업에서 계정을 변경한 경우 (예: IdP에서 '다른 계정 사용' 기능을 제공하거나 위임 케이스인 경우) resolve 호출은 선택적 두 번째 인수를 사용하여 다음과 같은 작업을 허용합니다.
IdentityProvider.resolve(token, {accountId: '1234');
오류 응답 반환
id_assertion_endpoint
는 두 가지 선택사항 필드가 있는 'error' 응답을 반환할 수도 있습니다.
code
: IdP는 OAuth 2.0 지정 오류 목록(invalid_request
,unauthorized_client
,access_denied
,server_error
,temporarily_unavailable
)에서 알려진 오류 중 하나를 선택하거나 임의의 문자열을 사용할 수 있습니다. 후자인 경우 Chrome은 일반 오류 메시지로 오류 UI를 렌더링하고 코드를 RP에 전달합니다.url
: 사용자에게 오류에 관한 추가 정보를 제공하기 위해 오류에 관한 정보가 포함된 사람이 읽을 수 있는 웹페이지를 식별합니다. 이 필드는 브라우저가 내장 UI에서 풍부한 오류 메시지를 제공할 수 없으므로 사용자에게 유용합니다. 예: 다음 단계 링크 또는 고객 서비스 연락처 정보 사용자가 오류 세부정보와 해결 방법을 자세히 알아보려면 브라우저 UI에서 제공된 페이지를 방문하면 됩니다. URL은 IdPconfigURL
와 동일한 사이트여야 합니다.
// id_assertion_endpoint response
{
"error" : {
"code": "access_denied",
"url" : "https://idp.example/error?type=access_denied"
}
}
맞춤 계정 라벨
맞춤 계정 라벨을 사용하면 IdP가 라벨로 사용자 계정에 주석을 달 수 있으며 RP는 특정 라벨의 configURL
를 지정하여 특정 라벨이 있는 계정만 가져오도록 선택할 수 있습니다. 이는 RP가 특정 기준에 따라 계정을 필터링해야 하는 경우에 유용합니다(예: "developer"
또는 "hr"
와 같은 역할별 계정만 표시).
navigator.credentials.get()
호출에서 도메인 힌트 및 로그인 힌트 기능을 지정하여 유사한 필터링을 수행할 수 있습니다. 하지만 맞춤 계정 라벨은 구성 파일을 지정하여 사용자를 필터링할 수 있습니다. 이는 여러 configURL이 사용되는 경우에 특히 유용합니다. 맞춤 계정 라벨은 로그인 또는 도메인 힌트와 같은 RP가 아닌 IdP 서버에서 제공된다는 점에서도 다릅니다.
"developer"
및 "hr"
계정을 구분하려는 IdP를 생각해 보세요. 이를 위해 IdP는 각각 "developer"
및 "hr"
의 두 가지 configURL을 지원해야 합니다.
- 개발자 구성 파일
https://idp.example/developer/fedcm.json
에는"developer"
라벨이 있고 엔터프라이즈 구성 파일https://idp.example/hr/fedcm.json
에는"hr"
라벨이 있습니다.
// The developer config file at `https://idp.example/developer/fedcm.json`
{
"accounts_endpoint": "https://idp.example/accounts",
"client_metadata_endpoint": "/client_metadata",
"login_url": "https://idp.example/login",
"id_assertion_endpoint": "/assertion",
"accounts": {
// Account label
"include": "developer"
}
}
// The hr config file at `https://idp.example/hr/fedcm.json`
{
"accounts_endpoint": "https://idp.example/accounts",
"client_metadata_endpoint": "/client_metadata",
"login_url": "https://idp.example/login",
"id_assertion_endpoint": "/assertion",
"accounts": {
// Account label
"include": "hr"
}
}
- 이러한 설정으로 well-known 파일에는 여러 configURL을 허용하기 위해
accounts_endpoint
및login_url
가 포함되어야 합니다.
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
- 공통 IdP 계정 엔드포인트 (이 예에서는
https://idp.example/accounts
)는 각 계정의 배열에 할당된 라벨이 있는labels
속성이 포함된 계정 목록을 반환합니다.
{
"accounts": [{
"id": "123",
"given_name": "John",
"name": "John Doe",
"email": "john_doe@idp.example",
"picture": "https://idp.example/profile/123",
"labels": ["developer"]
}], [{
"id": "4567",
"given_name": "Jane",
"name": "Jane Doe",
"email": "jane_doe@idp.example",
"picture": "https://idp.example/profile/4567",
"labels": ["hr"]
}]
}
RP가 "hr"
사용자의 로그인을 허용하려면 navigator.credentials.get()
호출에서 configURL https://idp.example/hr/fedcm.json
을 지정하면 됩니다.
let { token } = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
nonce: '234234',
configURL: 'https://idp.example/hr/fedcm.json',
},
}
});
따라서 사용자는 4567
의 계정 ID만 사용하여 로그인할 수 있습니다. 123
의 계정 ID는 브라우저에 의해 자동으로 숨겨지므로 사용자가 이 사이트의 IdP에서 지원하지 않는 계정을 제공받지 못합니다.
- 라벨은 문자열입니다.
labels
배열 또는include
필드에 문자열이 아닌 항목이 포함된 경우 무시됩니다. configURL
에 라벨이 지정되지 않은 경우 FedCM 계정 선택기에 모든 계정이 표시됩니다.- 계정에 라벨이 지정되지 않은 경우
configURL
에서도 라벨을 지정하지 않은 경우에만 계정 선택기에 표시됩니다. - 패시브 모드에서 요청된 라벨과 일치하는 계정이 없는 경우 (도메인 힌트 기능과 유사) FedCM 대화상자에 로그인 메시지가 표시되어 사용자가 IdP 계정에 로그인할 수 있습니다. 활성 모드의 경우 로그인 팝업 창이 바로 열립니다.
엔드포인트 연결 해제
IdentityCredential.disconnect()
를 호출하면 브라우저는 SameSite=None
가 포함된 쿠키와 콘텐츠 유형이 application/x-www-form-urlencoded
인 교차 출처 POST
요청을 다음 정보와 함께 이 연결 해제 엔드포인트로 전송합니다.
속성 | 설명 |
---|---|
account_hint |
IdP 계정에 대한 힌트입니다. |
client_id |
RP의 클라이언트 식별자입니다. |
POST /disconnect.example HTTP/1.1
Host: idp.example
Origin: rp.example
Content-Type: application/x-www-form-urlencoded
Cookie: 0x123
Sec-Fetch-Dest: webidentity
account_hint=account456&client_id=rp123
서버는 요청을 수신하면 다음을 실행해야 합니다.
- CORS (교차 출처 리소스 공유)를 사용하여 요청에 응답합니다.
- 요청에
Sec-Fetch-Dest: webidentity
HTTP 헤더가 포함되어 있는지 확인합니다. Origin
헤더를client_id
에 의해 결정된 RP 출처와 일치시킵니다. 일치하지 않으면 거부합니다.account_hint
를 이미 로그인한 계정의 ID와 일치시킵니다.- RP에서 사용자 계정의 연결을 해제합니다.
- 식별된 사용자 계정 정보를 JSON 형식으로 브라우저에 응답합니다.
응답 JSON 페이로드의 예는 다음과 같습니다.
{
"account_id": "account456"
}
대신 IdP에서 브라우저가 RP와 연결된 모든 계정의 연결을 해제하기를 원하는 경우 계정 ID와 일치하지 않는 문자열(예: "*"
)을 전달합니다.
클라이언트 메타데이터 엔드포인트
IdP의 클라이언트 메타데이터 엔드포인트는 RP의 개인정보처리방침, 서비스 약관, 로고 아이콘과 같은 신뢰 당사자의 메타데이터를 반환합니다. RP는 개인정보처리방침 및 서비스 약관 링크를 IdP에 사전에 제공해야 합니다. 이 링크는 사용자가 아직 IdP로 RP에 등록하지 않은 경우 로그인 대화상자에 표시됩니다.
브라우저가 쿠키 없이 client_id
navigator.credentials.get
를 사용하여 GET
요청을 보냅니다. 예를 들면 다음과 같습니다.
GET /client_metadata.example?client_id=1234 HTTP/1.1
Host: accounts.idp.example
Origin: https://rp.example/
Accept: application/json
Sec-Fetch-Dest: webidentity
서버는 요청을 수신하면 다음을 실행해야 합니다.
client_id
의 RP를 확인합니다.- 클라이언트 메타데이터로 응답합니다.
클라이언트 메타데이터 엔드포인트의 속성에는 다음이 포함됩니다.
속성 | 설명 |
---|---|
privacy_policy_url (선택사항) |
RP 개인정보처리방침 URL |
terms_of_service_url (선택사항) |
RP 서비스 약관 URL입니다. |
icons (선택사항) |
객체 배열(예: [{ "url": "https://rp.example/rp-icon.ico", "size": 40}] ) |
브라우저는 엔드포인트에서 JSON 응답을 예상합니다.
{
"privacy_policy_url": "https://rp.example/privacy_policy.html",
"terms_of_service_url": "https://rp.example/terms_of_service.html",
"icons": [{
"url": "https://rp.example/rp-icon.ico",
"size": 40
}]
}
반환된 클라이언트 메타데이터는 브라우저에서 사용하며 RP에서는 사용할 수 없습니다.
로그인 URL
이 엔드포인트는 사용자가 IdP에 로그인할 수 있도록 하는 데 사용됩니다.
로그인 상태 API를 사용하면 IdP가 사용자의 로그인 상태를 브라우저에 알려야 합니다. 그러나 세션이 만료되는 경우와 같이 상태가 동기화되지 않을 수 있습니다. 이러한 시나리오에서 브라우저는 idp 구성 파일의 login_url
로 지정된 로그인 페이지 URL을 통해 사용자가 IdP에 동적으로 로그인하도록 허용할 수 있습니다.
FedCM 대화상자에는 다음 이미지와 같이 로그인을 제안하는 메시지가 표시됩니다.
사용자가 계속 버튼을 클릭하면 브라우저에서 IdP 로그인 페이지의 팝업 창을 엽니다.
대화상자는 퍼스트 파티 쿠키가 있는 일반 브라우저 창입니다. 대화상자 내에서 발생하는 모든 상황은 IdP에 따라 다르며 RP 페이지에 교차 출처 통신 요청을 실행할 수 있는 창 핸들은 없습니다. 사용자가 로그인한 후 IdP는 다음을 실행해야 합니다.
Set-Login: logged-in
헤더를 전송하거나navigator.login.setStatus("logged-in")
API를 호출하여 사용자가 로그인했음을 브라우저에 알립니다.IdentityProvider.close()
를 호출하여 대화상자를 닫습니다.
브라우저에 사용자의 로그인 상태 알림
로그인 상태 API는 웹사이트, 특히 IdP가 브라우저에 IdP의 사용자 로그인 상태를 알리는 메커니즘입니다. 이 API를 사용하면 브라우저가 IdP에 대한 불필요한 요청을 줄이고 잠재적인 타이밍 공격을 완화할 수 있습니다.
IdP는 사용자가 IdP에 로그인했거나 모든 IdP 계정에서 로그아웃했을 때 HTTP 헤더를 전송하거나 JavaScript API를 호출하여 브라우저에 사용자의 로그인 상태를 알릴 수 있습니다. 각 IdP (구성 URL로 식별됨)의 경우 브라우저는 로그인 상태를 나타내는 3중 상태 변수를 유지하며 가능한 값은 다음과 같습니다.
logged-in
logged-out
unknown
(기본)
로그인 상태 | 설명 |
---|---|
logged-in |
사용자의 로그인 상태가 logged-in 로 설정되면 FedCM을 호출하는 RP가 IdP의 계정 엔드포인트에 요청하고 FedCM 대화상자에 사용 가능한 계정을 사용자에게 표시합니다. |
logged-out |
사용자의 로그인 상태가 logged-out 인 경우 FedCM을 호출하면 IdP의 계정 엔드포인트에 요청하지 않고도 자동으로 실패합니다. |
unknown (기본) |
unknown 상태는 IdP가 Login Status API를 사용하여 신호를 보내기 전에 설정됩니다. 상태가 unknown 이면 브라우저가 IdP의 계정 엔드포인트에 요청을 전송하고 계정 엔드포인트의 응답을 기반으로 상태를 업데이트합니다. |
사용자가 로그인했음을 알리려면 최상위 탐색의 Set-Login: logged-in
HTTP 헤더 또는 IdP 출처의 동일 사이트 하위 리소스 요청을 전송합니다.
Set-Login: logged-in
또는 최상위 탐색의 IdP 출처에서 JavaScript 메서드 navigator.login.setStatus('logged-in')
를 호출합니다.
navigator.login.setStatus('logged-in')
사용자의 로그인 상태가 logged-in
로 설정됩니다.
사용자가 모든 계정에서 로그아웃되었음을 알리려면 최상위 탐색의 Set-Login: logged-out
HTTP 헤더를 전송하거나 IdP 출처에서 동일 사이트 하위 리소스 요청을 전송합니다.
Set-Login: logged-out
또는 최상위 탐색의 IdP 출처에서 JavaScript API navigator.login.setStatus('logged-out')
를 호출합니다.
navigator.login.setStatus('logged-out')
사용자의 로그인 상태가 logged-out
로 설정됩니다.
unknown
상태는 IdP가 Login Status API를 사용하여 신호를 보내기 전에 설정됩니다. 브라우저가 IdP의 계정 엔드포인트에 요청을 보내고 계정 엔드포인트의 응답을 기반으로 상태를 업데이트합니다.
- 엔드포인트가 활성 계정 목록을 반환하면 상태를
logged-in
로 업데이트하고 FedCM 대화상자를 열어 해당 계정을 표시합니다. - 엔드포인트에서 계정을 반환하지 않으면 상태를
logged-out
로 업데이트하고 FedCM 호출을 실패로 처리합니다.
사용자가 동적 로그인 흐름을 통해 로그인하도록 허용
IdP가 계속해서 사용자의 로그인 상태를 브라우저에 알리더라도 세션이 만료되는 경우와 같이 동기화되지 않을 수 있습니다. 로그인 상태가 logged-in
인 경우 브라우저는 계정 엔드포인트에 사용자 인증 정보가 포함된 요청을 전송하려고 하지만 세션을 더 이상 사용할 수 없으므로 서버는 계정을 반환하지 않습니다. 이러한 시나리오에서 브라우저는 팝업 창을 통해 사용자가 IdP에 동적으로 로그인하도록 허용할 수 있습니다.
FedCM을 RP로 구현
IdP의 구성과 엔드포인트를 사용할 수 있게 되면 RP는 navigator.credentials.get()
를 호출하여 사용자가 IdP로 RP에 로그인할 수 있도록 허용해 달라고 요청할 수 있습니다.
API를 호출하기 전에 사용자의 브라우저에서 FedCM을 사용할 수 있는지 확인해야 합니다. FedCM을 사용할 수 있는지 확인하려면 FedCM 구현을 둘러싸고 다음 코드를 래핑합니다.
if ('IdentityCredential' in window) {
// If the feature is available, take action
} else {
// FedCM is not supported, use a different identity solution
}
사용자가 FedCM을 사용하여 RP의 IdP에 로그인할 수 있도록 하려면 RP에서 navigator.credentials.get()
를 호출하면 됩니다. 예를 들면 다음과 같습니다.
const credential = await navigator.credentials.get({
identity: {
context: 'signin',
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
mode: 'active',
params: {
nonce: '******'
}
}]
}
});
const { token } = credential;
컨텍스트 속성
선택적 context
속성을 사용하면 RP가 사전 정의된 인증 컨텍스트를 수용하도록 FedCM 대화상자 UI의 문자열 (예: 'rp.example에 로그인…', 'idp.example 사용…')을 수정할 수 있습니다. context
속성은 다음 값을 가질 수 있습니다.
signin
(기본)signup
use
예를 들어 context
를 use
로 설정하면 다음 메시지가 표시됩니다.
브라우저는 계정 목록 엔드포인트의 응답에 approved_clients
가 있는지 여부에 따라 가입 및 로그인 사용 사례를 다르게 처리합니다. 사용자가 이미 RP에 가입한 경우 브라우저에 '계속하려면...'이라는 공개 문구가 표시되지 않습니다.
providers
속성은 다음 속성을 갖는 IdentityProvider 객체 배열을 취합니다.
제공업체 속성
providers
속성은 다음 속성을 갖는 IdentityProvider
객체 배열을 취합니다.
속성 | 설명 |
---|---|
configURL (필수) |
IdP 구성 파일의 전체 경로입니다. |
clientId (필수) |
IdP에서 발급한 RP의 클라이언트 식별자입니다. |
nonce (선택사항) |
이 특정 요청에 대한 응답이 발행되도록 하는 임의의 문자열입니다. 재전송 공격을 방지합니다. |
loginHint (선택사항) |
계정 엔드포인트에서 제공하는 login_hints 값 중 하나를 지정하면 FedCM 대화상자에 지정된 계정이 선택적으로 표시됩니다. |
domainHint (선택사항) |
계정 엔드포인트에서 제공하는 domain_hints 값 중 하나를 지정하면 FedCM 대화상자에 지정된 계정이 선택적으로 표시됩니다. |
mode (선택사항) |
FedCM의 UI 모드를 지정하는 문자열입니다. 다음 값 중 하나일 수 있습니다.
참고: mode 매개변수는 Chrome 132부터 지원됩니다.
|
fields (선택사항) |
RP가 IdP와 공유해야 하는 사용자 정보 ('이름', '이메일', '사진')를 지정하는 문자열 배열입니다. 참고: Field API는 Chrome 132 이상에서 지원됩니다. |
parameters (선택사항) |
키-값 매개변수를 추가로 지정할 수 있는 맞춤 객체입니다.
참고: parameters 는 Chrome 132부터 지원됩니다.
|
활성 모드
FedCM은 다양한 UX 모드 구성을 지원합니다. 수동 모드는 기본 모드이며 개발자가 구성할 필요가 없습니다.
활성 모드에서 FedCM을 사용하려면 다음 단계를 따르세요.
- 사용자의 브라우저에서 기능 사용 가능 여부를 확인합니다.
- 버튼 클릭과 같은 일시적인 사용자 동작으로 API를 호출합니다.
mode
매개변수를 API 호출에 전달합니다.
let supportsFedCmMode = false;
try {
navigator.credentials.get({
identity: Object.defineProperty(
// Check if this Chrome version supports the Mode API.
{}, 'mode', {
get: function () { supportsFedCmMode = true; }
}
)
});
} catch(e) {}
if (supportsFedCmMode) {
// The button mode is supported. Call the API with mode property:
return await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/config.json',
clientId: '123',
}],
// The 'mode' value defines the UX mode of FedCM.
// - 'active': Must be initiated by user interaction (e.g., clicking a button).
// - 'passive': Can be initiated without direct user interaction.
mode: 'active'
}
});
}
활성 모드의 맞춤 아이콘
활성 모드를 사용하면 IdP가 클라이언트 메타데이터 엔드포인트 응답에 RP의 공식 로고 아이콘을 직접 포함할 수 있습니다. RP는 브랜딩 데이터를 사전에 제공해야 합니다.
교차 출처 iframe 내에서 FedCM 호출
상위 프레임에서 허용하는 경우 identity-credentials-get
권한 정책을 사용하여 교차 출처 iframe 내에서 FedCM을 호출할 수 있습니다. 이렇게 하려면 다음과 같이 allow="identity-credentials-get"
속성을 iframe 태그에 추가합니다.
<iframe src="https://fedcm-cross-origin-iframe.glitch.me" allow="identity-credentials-get"></iframe>
예시에서 작동 방식을 확인할 수 있습니다.
원하는 경우 상위 프레임에서 FedCM을 호출하는 출처를 제한하려면 허용된 출처 목록이 포함된 Permissions-Policy
헤더를 전송합니다.
Permissions-Policy: identity-credentials-get=(self "https://fedcm-cross-origin-iframe.glitch.me")
권한 정책으로 브라우저 기능 제어에서 권한 정책의 작동 방식을 자세히 알아보세요.
Login Hint API
RP는 로그인 힌트를 사용하여 사용자가 로그인해야 하는 계정을 추천할 수 있습니다. 이는 이전에 사용한 계정이 무엇인지 모르는 사용자를 재인증하는 데 유용할 수 있습니다.
RP는 다음 코드 샘플과 같이 계정 목록 엔드포인트에서 가져온 login_hints
값 중 하나를 사용하여 loginHint
속성으로 navigator.credentials.get()
를 호출하여 특정 계정을 선택적으로 표시할 수 있습니다.
return await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/manifest.json',
clientId: '123',
// Accounts endpoint can specify a 'login_hints' array for an account.
// When RP specifies a 'exampleHint' value, only those accounts will be
// shown to the user whose 'login_hints' array contains the 'exampleHint'
// value
loginHint : 'exampleHint'
}]
}
});
loginHint
와 일치하는 계정이 없으면 FedCM 대화상자에 로그인 메시지가 표시되며 이를 통해 사용자는 RP에서 요청한 힌트와 일치하는 IdP 계정에 로그인할 수 있습니다. 사용자가 프롬프트를 탭하면 구성 파일에 지정된 로그인 URL이 포함된 팝업 창이 열립니다. 그런 다음 링크에 로그인 힌트 및 도메인 힌트 쿼리 매개변수가 추가됩니다.
Domain Hint API
RP는 특정 도메인과 연결된 계정만 선택적으로 표시할 수 있습니다. 이는 기업 도메인으로 제한된 RP에 유용할 수 있습니다.
특정 도메인 계정만 표시하려면 RP는 다음 코드 샘플과 같이 계정 목록 엔드포인트에서 가져온 domain_hints
값 중 하나를 사용하여 domainHint
속성으로 navigator.credentials.get()
를 호출해야 합니다.
return await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/manifest.json',
clientId: 'abc',
// Accounts endpoint can specify a 'domain_hints' array for an account.
// When RP specifies a '@domain.example' value, only those accounts will be
// shown to the user whose 'domain_hints' array contains the
// '@domain.example' value
domainHint : '@domain.example'
}]
}
});
domainHint
와 일치하는 계정이 없으면 FedCM 대화상자에 로그인 메시지가 표시되며, 이를 통해 사용자는 RP에서 요청한 힌트와 일치하는 IdP 계정에 로그인할 수 있습니다. 사용자가 프롬프트를 탭하면 구성 파일에 지정된 로그인 URL이 포함된 팝업 창이 열립니다. 그런 다음 링크에 로그인 힌트 및 도메인 힌트 쿼리 매개변수가 추가됩니다.
맞춤 매개변수
맞춤 매개변수 기능을 사용하면 RP가 ID 어설션 엔드포인트에 키-값 매개변수를 추가로 제공할 수 있습니다. RP는 Parameters API를 사용하여 IdP에 추가 매개변수를 전달하여 기본 로그인 외의 리소스에 대한 권한을 요청할 수 있습니다. 다음과 같은 시나리오에서는 추가 매개변수를 전달하는 것이 유용할 수 있습니다.
- RP는 결제 주소 또는 캘린더 액세스와 같이 IdP에 있는 추가 권한을 동적으로 요청해야 합니다. 사용자는 계속 기능을 사용하여 실행되는 IdP 제어 UX 흐름을 통해 이러한 권한을 승인할 수 있으며, 그러면 IdP에서 이 정보를 공유합니다.
API를 사용하기 위해 RP는 navigator.credentials.get()
호출에서 객체로 params
속성에 매개변수를 추가합니다.
let {token} = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
configURL: 'https://idp.example/fedcm.json',
// Key/value pairs that need to be passed from the
// RP to the IdP but that don't really play any role with
// the browser.
params: {
IDP_SPECIFIC_PARAM: '1',
foo: 'BAR'
}
},
}
});
브라우저는 이를 자동으로 IdP에 대한 POST 요청으로 변환하며, 이때 매개변수는 단일 URL 인코딩 JSON 직렬화 객체로 표시됩니다.
// The assertion endpoint is drawn from the config file
POST /fedcm_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
// params are translated into urlencoded version of `{"IDP_SPECIFIC_PARAM":"1","foo":"bar"}`
account_id=123&client_id=client1234¶ms=%22%7B%5C%22IDP_SPECIFIC_PARAM%5C%22%3A1%2C%5C%22foo%5C%22%3A%5C%22BAR%5C%22%7D%22.
RP에 추가 권한이 필요한 경우 IdP에서 리디렉션 링크를 제공할 수 있습니다. 예를 들어 node.js에서:
if (rpRequestsPermissions) {
// Response with a URL if the RP requests additional permissions
return res.json({
continue_on: '/example-redirect',
});
}
필드
RP는 IdP가 공유해야 하는 사용자 정보 (이름, 이메일 주소, 프로필 사진의 조합)를 지정할 수 있습니다. 요청된 정보는 FedCM 대화상자의 공개 UI에 포함됩니다. 사용자가 로그인을 선택하면 idp.example
에서 요청된 정보를 rp.example
와 공유한다는 알림 메시지가 표시됩니다.
필드 기능을 사용하려면 RP가 navigator.credentials.get()
호출에 fields
배열을 추가해야 합니다. 이 필드에는 name
, email
, picture
의 모든 순열이 포함될 수 있습니다. 향후 더 많은 값을 포함하도록 확장될 수 있습니다.
fields
가 포함된 요청은 다음과 같습니다.
let { token } = await navigator.credentials.get({
identity: {
providers: [{
// RP requests the IdP to share only user email and profile picture
fields: [ 'email', 'picture'],
clientId: '1234',
configURL: 'https://idp.example/fedcm.json',
},
}
});
브라우저는 이를 자동으로 ID 어설션 엔드포인트에 대한 HTTP 요청으로 변환하며, 여기에는 RP가 지정한 fields
매개변수와 브라우저가 disclosure_shown_for
매개변수로 사용자에게 공개한 필드가 포함됩니다. 하위 호환성을 위해 브라우저는 공개 텍스트가 표시되었고 요청된 필드에 세 필드 모두('name'
, 'email'
, 'picture'
)가 포함된 경우에도 disclosure_text_shown=true
를 전송합니다.
POST /id_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
// The RP only requested to share email and picture. The browser will send `disclosure_text_shown=false`, as the 'name' field value is missing
account_id=123&client_id=client1234&disclosure_text_shown=false&fields=email,picture&disclosure_shown_for=email,picture
fields
가 빈 배열인 경우 사용자 에이전트는 공개 UI를 건너뜁니다.
이는 계정 엔드포인트의 응답에 approved_clients
의 RP와 일치하는 클라이언트 ID가 포함되지 않은 경우에도 마찬가지입니다.
이 경우 ID 어설션 엔드포인트로 전송된 disclosure_text_shown
가 HTTP 본문에서 false입니다.
POST /id_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false
오류 메시지 표시
클라이언트가 승인되지 않았거나 서버를 일시적으로 사용할 수 없는 경우와 같이 IdP가 합법적인 이유로 토큰을 발급하지 못할 수도 있습니다. IdP가 'error' 응답을 반환하면 RP가 이를 포착할 수 있으며 Chrome은 IdP에서 제공한 오류 정보가 포함된 브라우저 UI를 표시하여 사용자에게 알릴 수 있습니다.
try {
const cred = await navigator.credentials.get({
identity: {
providers: [
{
configURL: 'https://idp.example/manifest.json',
clientId: '1234',
},
],
}
});
} catch (e) {
const code = e.code;
const url = e.url;
}
최초 인증 후 사용자 자동 재인증
FedCM 자동 재인증(줄여서 '자동 재인증')을 사용하면 사용자가 FedCM을 사용하여 초기 인증 후 다시 방문할 때 자동으로 재인증할 수 있습니다. 여기서 '초기 인증'은 사용자가 동일한 브라우저 인스턴스에서 FedCM 로그인 대화상자의 '계정으로 계속...' 버튼을 탭하여 계정을 만들거나 RP 웹사이트에 로그인하는 것을 의미합니다.
명시적 사용자 환경은 사용자가 추적을 방지하기 위해 제휴 계정을 만들기 전에 적절하지만 (FedCM의 주요 목표 중 하나임) 사용자가 한 번 거친 후에는 불필요하게 번거로워집니다. 사용자가 RP와 IdP 간의 통신을 허용하기 위한 권한을 부여한 후에는 이미 이전에 확인한 사항에 대해 또다시 명시적 사용자 확인을 시행하는 데 어떠한 개인 정보 보호 또는 보안 이점도 없습니다.
자동 재인증을 사용하면 브라우저는 navigator.credentials.get()
를 호출할 때 mediation
에 지정하는 옵션에 따라 동작을 변경합니다.
const cred = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/fedcm.json',
clientId: '1234',
}],
},
mediation: 'optional', // this is the default
});
// `isAutoSelected` is `true` if auto-reauthn was performed.
const isAutoSelected = cred.isAutoSelected;
mediation
는 인증 관리 API의 속성이며 PasswordCredential 및 FederatedCredential과 동일한 방식으로 작동하며 PublicKeyCredential에서도 부분적으로 지원됩니다. 이 속성은 다음 4가지 값을 허용합니다.
'optional'
(기본값): 가능한 경우 자동 재인증, 불가능한 경우 미디에이션 필요 로그인 페이지에서 이 옵션을 선택하는 것이 좋습니다.'required'
: 항상 미디에이션이 필요합니다(예: UI에서 '계속' 버튼 클릭). 사용자가 인증해야 할 때마다 명시적으로 권한을 부여해야 하는 경우 이 옵션을 선택합니다.'silent'
: 가능하면 자동 재인증을 실행하고, 가능하지 않으면 미디에이션 없이 자동으로 실패합니다. 전용 로그인 페이지가 아닌 페이지에서 사용자를 로그인 상태로 유지하려는 경우 이 옵션을 선택하는 것이 좋습니다(예: 배송 웹사이트의 상품 페이지 또는 뉴스 웹사이트의 기사 페이지).'conditional'
: WebAuthn에 사용되며 현재 FedCM에는 사용할 수 없습니다.
이 호출을 사용하면 다음 조건에서 자동 재인증이 실행됩니다.
- FedCM을 사용할 수 있습니다. 예를 들어 사용자가 설정에서 전체적으로 또는 RP에 대해 FedCM을 사용 중지하지 않았습니다.
- 사용자가 이 브라우저에서 웹사이트에 로그인할 때 FedCM API와 함께 하나의 계정만 사용했습니다.
- 사용자가 해당 계정으로 IdP에 로그인합니다.
- 지난 10분 이내에 자동 재인증이 이루어지지 않았습니다.
- RP가 이전 로그인 후
navigator.credentials.preventSilentAccess()
를 호출하지 않았습니다.
이러한 조건이 충족되면 FedCM navigator.credentials.get()
이 호출되는 즉시 사용자를 자동으로 재인증하려는 시도가 시작됩니다.
mediation: optional
인 경우 브라우저만 알고 있는 이유로 인해 자동 재인증을 사용할 수 없음. RP는 isAutoSelected
속성을 검사하여 자동 재인증이 실행되는지 확인할 수 있습니다.
이렇게 하면 API 성능을 평가하고 그에 따라 UX를 개선하는 데 도움이 됩니다.
또한 사용할 수 없는 경우 사용자에게 mediation: required
가 포함된 흐름인 명시적 사용자 미디에이션으로 로그인하라는 메시지가 표시될 수 있습니다.
preventSilentAccess()
로 미디에이션 시행
사용자가 로그아웃한 직후에 자동으로 재인증하면 사용자 환경이 좋지 않을 수 있습니다. 이러한 동작을 방지하기 위해 FedCM에는 자동 재인증 후 10분의 대기 시간이 있습니다. 즉, 사용자가 10분 이내에 다시 로그인하지 않는 한 자동 재인증은 10분마다 최대 한 번씩 발생합니다. RP는 사용자가 로그아웃 버튼을 클릭하는 등 명시적으로 RP에서 로그아웃할 때 브라우저에 자동 재인증을 사용 중지하도록 명시적으로 요청하기 위해 navigator.credentials.preventSilentAccess()
를 호출해야 합니다.
function signout() {
navigator.credentials.preventSilentAccess();
location.href = '/signout';
}
사용자는 설정에서 자동 재인증을 선택 해제할 수 있습니다.
사용자는 설정 메뉴에서 자동 재인증을 선택 해제할 수 있습니다.
- 데스크톱 Chrome에서
chrome://password-manager/settings
> 자동 로그인으로 이동합니다. - Android Chrome에서 설정 > 비밀번호 관리자를 열고 오른쪽 상단의 톱니바퀴 아이콘을 탭한 다음 자동 로그인을 선택합니다.
전환 버튼을 사용 중지하면 사용자는 자동 재인증 동작을 모두 선택 해제할 수 있습니다. 사용자가 Chrome 인스턴스에서 Google 계정에 로그인되어 있고 동기화가 사용 설정된 경우 이 설정은 여러 기기에 저장되고 동기화됩니다.
RP에서 IdP 연결 해제
사용자가 이전에 FedCM을 통해 IdP를 사용하여 RP에 로그인한 경우 브라우저에서 연결된 계정 목록으로 로컬에 관계를 저장합니다. RP는 IdentityCredential.disconnect()
함수를 호출하여 연결 해제를 시작할 수 있습니다. 이 함수는 최상위 RP 프레임에서 호출할 수 있습니다. RP는 configURL
, IdP에서 사용하는 clientId
, IdP의 연결을 해제하기 위한 accountHint
를 전달해야 합니다. 계정 힌트는 연결 해제 엔드포인트에서 계정을 식별할 수 있는 한 임의의 문자열이 될 수 있습니다(예: 계정 목록 엔드포인트에서 제공한 계정 ID와 반드시 일치하지 않는 이메일 주소 또는 사용자 ID).
// Disconnect an IdP account 'account456' from the RP 'https://idp.com/'. This is invoked on the RP domain.
IdentityCredential.disconnect({
configURL: 'https://idp.com/config.json',
clientId: 'rp123',
accountHint: 'account456'
});
IdentityCredential.disconnect()
에서 Promise
를 반환합니다. 이 약속은 다음과 같은 이유로 예외를 발생시킬 수 있습니다.
- 사용자가 FedCM을 통해 IdP를 사용하여 RP에 로그인하지 않았습니다.
- API는 FedCM 권한 정책 없이 iframe 내에서 호출됩니다.
- configURL이 잘못되었거나 연결 해제 엔드포인트가 누락되었습니다.
- 콘텐츠 보안 정책 (CSP) 확인에 실패합니다.
- 대기 중인 연결 해제 요청이 있습니다.
- 사용자가 브라우저 설정에서 FedCM을 사용 중지했습니다.
IdP의 연결 해제 엔드포인트가 응답을 반환하면 브라우저에서 RP와 IdP의 연결이 해제되고 약속이 해결됩니다. 연결 해제된 계정의 ID는 연결 해제 엔드포인트의 응답에 지정됩니다.