Chrome 126부터 개발자는 일부 승인 사용 사례를 지원하는 데스크톱 제휴 사용자 인증 정보 관리 API (FedCM) 기능 번들의 오리진 트라이얼을 실행할 수 있습니다. 이 번들은 ID 공급업체 (IDP)에서 제공하는 권한 대화상자가 포함된 OAuth 승인 흐름과 같은 환경을 지원하는 Continuation API 및 Parameters API로 구성됩니다. 이 번들에는 Fields API, 여러 configURL, 맞춤 계정 라벨과 같은 다른 변경사항도 포함되어 있습니다. Chrome 126부터 사용자가 이전에 FedCM을 사용하여 로그인한 적이 있는 경우 SAA 요청을 자동으로 부여하는 Storage Access API (SAA)의 출처 체험판도 도입됩니다.
오리진 트라이얼: FedCM 연속 API 번들
FedCM 연속 API 번들은 여러 FedCM 확장 프로그램으로 구성됩니다.
Continuation API
Glitch에서 API 데모를 확인할 수 있습니다.
연속 API를 사용하면 IdP의 ID 어설션 엔드포인트가 선택적으로 FedCM이 렌더링하여 사용자가 다단계 로그인 흐름을 계속할 수 있는 URL을 반환할 수 있습니다. 이를 통해 IdP는 사용자에게 기존 FedCM UI에서 가능한 것 이상의 신뢰 당사자(RP) 권한을 부여하도록 요청할 수 있습니다(예: 사용자의 서버 측 리소스에 대한 액세스).
일반적으로 ID 어설션 엔드포인트는 인증에 필요한 토큰을 반환합니다.
{
"token": "***********"
}
그러나 연속 API를 사용하면 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 pop-up window:
"continue_on": "/oauth/authorize?scope=..."
}
브라우저가 continue_on
응답을 수신하는 즉시 새 팝업 창이 열리고 사용자를 지정된 경로로 안내합니다.
사용자가 페이지와 상호작용(예: RP와 추가 정보를 공유하기 위한 추가 권한 부여)한 후 IdP 페이지는 IdentityProvider.resolve()
를 호출하여 원래 navigator.credentials.get()
호출을 확인하고 토큰을 인수로 반환할 수 있습니다.
document.getElementById('allow_btn').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.close()
를 호출하여 창을 닫을 수 있습니다.
IdentityProvider.close();
어떤 이유로든 사용자가 팝업에서 계정을 변경한 경우 (예: IdP에서 '사용자 전환' 함수를 제공하거나 위임 케이스인 경우) resolve 호출은 다음과 같은 작업을 허용하는 선택적 두 번째 인수를 사용합니다.
IdentityProvider.resolve(token, {accountId: '1234');
Parameters API
Parameters API를 사용하면 RP가 ID 어설션 엔드포인트에 추가 매개변수를 제공할 수 있습니다. RP는 Parameters API를 사용하여 IdP에 추가 매개변수를 전달하여 기본 로그인 외의 리소스에 대한 권한을 요청할 수 있습니다. 사용자는 연속 API를 통해 실행되는 IdP 제어 UX 흐름을 통해 이러한 권한을 승인합니다.
API를 사용하려면 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',
ETC: 'MOAR',
scope: 'calendar.readonly photos.write',
}
},
}
});
params
객체의 속성 이름 앞에는 param_
이 추가됩니다. 위 예에서 params 속성에는 IDP_SPECIFIC_PARAM
가 '1'
로, foo
가 'BAR'
로, ETC
가 'MOAR'
로, scope
가 'calendar.readonly photos.write'
로 포함되어 있습니다.
이는 요청의 HTTP 본문에서 param_IDP_SPECIFIC_PARAM=1¶m_foo=BAR¶m_ETC=MOAR¶m_scope=calendar.readonly%20photos.write
로 변환됩니다.
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
account_id=123&client_id=client1234&nonce=234234&disclosure_text_shown=false¶m_IDP_SPECIFIC_PARAM=1¶m_foo=BAR¶m_ETC=MOAR¶m_scope=calendar.readonly%20photos.write
동적으로 권한 가져오기
일반적으로 사용자에게는 개발자가 구현하기 가장 쉽다고 생각하는 시점이 아니라 필요한 시점에 권한을 요청하는 것이 가장 유용합니다. 예를 들어 사용자가 웹사이트에 도달하자마자 권한을 요청하는 것보다 사용자가 사진을 찍으려 할 때 카메라에 액세스할 권한을 요청하는 것이 좋습니다. 서버 리소스에도 동일한 관행이 적용됩니다. 사용자에게 권한이 필요한 경우에만 권한을 요청합니다. 이를 '동적 승인'이라고 합니다.
FedCM으로 동적으로 승인을 요청하려면 IdP는 다음을 실행할 수 있습니다.
- IdP가 이해할 수 있는 필수 매개변수(예:
scope
)를 사용하여navigator.credentials.get()
를 호출합니다. - ID 어설션 엔드포인트는 사용자가 이미 로그인했음을 확인하고
continue_on
URL로 응답합니다. - 브라우저에 요청된 범위와 일치하는 추가 권한을 요청하는 IdP의 권한 페이지가 포함된 팝업 창이 열립니다.
- IdP에서
IdentityProvider.resolve()
를 통해 승인되면 창이 닫히고 RP의 원래navigator.credentials.get()
호출은 관련 토큰 또는 승인 코드를 가져와 RP가 적절한 액세스 토큰으로 교환할 수 있도록 합니다.
Fields API
Fields API를 사용하면 RP가 브라우저가 FedCM 대화상자에 적절한 공개 UI를 렌더링할 수 있도록 IdP에 요청할 계정 속성을 선언할 수 있습니다. 반환된 토큰에 요청된 필드를 포함하는 것은 IdP의 책임입니다. OpenID Connect에서 '기본 프로필'을 요청하는 것과 OAuth에서 '범위'를 요청하는 것을 예로 들 수 있습니다.


Fields API를 사용하려면 navigator.credentials.get()
호출에서 fields
속성에 매개변수를 배열로 추가합니다. 이 필드는 현재 'name'
, 'email'
, 'picture'
를 포함할 수 있지만 향후 더 많은 값을 포함하도록 확장될 수 있습니다.
fields
가 포함된 요청은 다음과 같습니다.
let { token } = await navigator.credentials.get({
identity: {
providers: [{
fields: ['name', 'email', 'picture'],
clientId: '1234',
configURL: 'https://idp.example/fedcm.json',
params: {
scope: 'drive.readonly calendar.readonly',
}
},
}
mediation: 'optional',
});
ID 어설션 엔드포인트에 대한 HTTP 요청에는 RP가 지정한 fields
매개변수가 포함되며, 재방문자가 아닌 경우 disclosure_text_shown
매개변수가 true
로 설정됩니다. 또한 브라우저가 disclosure_shown_for
매개변수로 사용자에게 공개한 필드도 포함됩니다.
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=true&fields=email,name,picture&disclosure_shown_for=email,name,picture
RP가 캘린더 액세스와 같은 IdP의 추가 데이터에 액세스해야 하는 경우 위에서 언급한 대로 맞춤 매개변수로 처리해야 합니다. IdP는 권한을 요청하는 continue_on
URL을 반환합니다.
fields
가 빈 배열인 경우 요청은 다음과 같습니다.
let { token } = await navigator.credentials.get({
identity: {
providers: [{
fields: [],
clientId: '1234',
configURL: 'https://idp.example/fedcm.json',
params: {
scope: 'drive.readonly calendar.readonly',
}
},
}
mediation: 'optional',
});
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
여러 configURL
다중 configURL을 사용하면 IdP가 잘 알려진 파일에서 구성 파일과 동일한 accounts_endpoint
및 login_url
를 지정하여 IdP의 여러 구성 파일을 수용할 수 있습니다.
accounts_endpoint
및 login_url
가 well-known 파일에 추가되면 IdP가 여러 구성 파일을 지원할 수 있도록 provider_urls
가 무시됩니다.
그렇지 않은 경우 provider_urls
는 이전 버전과 호환되도록 계속 적용됩니다.
여러 configURL을 지원하는 잘 알려진 파일은 다음과 같이 표시될 수 있습니다.
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
이를 통해 다음 작업을 할 수 있습니다.
- 기존의 잘 알려진 파일 및 이미 배포된 이전 버전의 브라우저와의 호환성을 유지합니다.
- 구성 파일의 수는 임의로 지정할 수 있습니다. 단, 모두 동일한
accounts_endpoint
및login_url
를 가리켜야 합니다. - 엔트로피는 '.well-known' 수준에서 지정해야 하므로
accounts_endpoint
에 대한 사용자 인증 정보 가져오기 요청에 엔트로피를 추가할 기회가 없습니다.
여러 configURL을 지원하는 것은 선택사항이며 기존 FedCM 구현은 동일하게 유지될 수 있습니다.
맞춤 계정 라벨
맞춤 계정 라벨을 사용하면 FedCM IdP가 계정에 주석을 달아 RP가 구성 파일에서 라벨을 지정하여 계정을 필터링할 수 있습니다. navigator.credentials.get()
호출에서 Domain Hint API 및 Login Hint API를 지정하여 유사한 필터링을 수행할 수 있었지만 맞춤 계정 라벨은 구성 파일을 지정하여 사용자를 필터링할 수 있습니다. 이는 여러 configURL이 사용되는 경우에 특히 유용합니다. 맞춤 계정 라벨은 로그인 또는 도메인 힌트와 같은 RP가 아닌 IdP 서버에서 제공된다는 점에서 다릅니다.
예
IdP는 각각 소비자와 기업용의 두 가지 configURL을 지원합니다. 소비자 구성 파일에는 'consumer'
라벨이 있고 엔터프라이즈 구성 파일에는 'enterprise'
라벨이 있습니다.
이러한 설정을 사용하면 잘 알려진 파일에 accounts_endpoint
및 login_url
가 포함되어 여러 configURL을 허용합니다.
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
accounts_endpoint
가 잘 알려진 파일에 제공되면 provider_urls
는 무시됩니다. RP는 navigator.credentials.get()
호출에서 각 구성 파일을 직접 가리킬 수 있습니다.
소비자 구성 파일은 https://idp.example/fedcm.json
에 있으며 여기에는 include
를 사용하여 'consumer'
를 지정하는 accounts
속성이 포함되어 있습니다.
{
"accounts_endpoint": "https://idp.example/accounts",
"client_metadata_endpoint": "/client_metadata",
"login_url": "https://idp.example/login",
"id_assertion_endpoint": "/assertion",
"accounts": {
"include": "consumer"
}
}
엔터프라이즈 구성 파일은 https://idp.example/enterprise/fedcm.json
에 있으며 여기에는 include
를 사용하여 'enterprise'
를 지정하는 accounts
속성이 포함되어 있습니다.
{
"accounts_endpoint": "https://idp.example/accounts",
"client_metadata_endpoint": "/enterprise/client_metadata",
"login_url": "https://idp.example/login",
"id_assertion_endpoint": "/assertion",
"accounts": {
"include": "enterprise"
}
}
공통 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": ["consumer"]
}], [{
"id": "4567",
"given_name": "Jane",
"name": "Jane Doe",
"email": "jane_doe@idp.example",
"picture": "https://idp.example/profile/4567",
"labels": ["enterprise"]
}]
}
RP가 'enterprise'
사용자의 로그인을 허용하려면 navigator.credentials.get()
호출에서 'enterprise'
configURL 'https://idp.example/enterprise/fedcm.json'
을 지정하면 됩니다.
let { token } = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
nonce: '234234',
configURL: 'https://idp.example/enterprise/fedcm.json',
},
}
});
따라서 사용자는 '4567'
의 계정 ID만 사용하여 로그인할 수 있습니다. '123'
의 계정 ID는 브라우저에 의해 자동으로 숨겨지므로 사용자에게 이 사이트의 IdP에서 지원하지 않는 계정이 제공되지 않습니다.
오리진 트라이얼: Storage Access API의 신뢰 신호로서 FedCM
Chrome 126에서는 FedCM을 스토리지 액세스 API의 신뢰 신호로 사용하는 오리진 트라이얼을 시작합니다. 이번 변경으로 FedCM을 통한 이전 권한 부여는 Storage Access API의 스토리지 액세스 요청을 자동으로 승인할 수 있는 유효한 이유가 됩니다.
이는 삽입된 iframe이 맞춤설정된 리소스에 액세스하려는 경우에 유용합니다. 예를 들어 idp.example이 rp.example에 삽입되어 있고 맞춤설정된 리소스를 표시해야 하는 경우입니다. 브라우저에서 서드 파티 쿠키에 대한 액세스를 제한하는 경우 사용자가 FedCM과 함께 idp.example을 사용하여 rp.example에 로그인한 경우에도 삽입된 idp.example iframe은 맞춤 리소스를 요청할 수 없습니다. 요청에 서드 파티 쿠키가 포함되지 않기 때문입니다.
이를 위해 idp.example은 웹사이트에 삽입된 iframe을 통해 저장소 액세스 권한을 가져와야 하며, 이는 권한 메시지를 통해서만 얻을 수 있습니다.
FedCM을 Storage Access API의 신뢰 신호로 사용하면 Storage Access API 권한 확인은 스토리지 액세스 메시지에 의해 부여된 권한 부여뿐만 아니라 FedCM 메시지에 의해 부여된 권한 부여도 허용합니다.
// In top-level rp.example:
// Ensure FedCM permission has been granted.
const cred = await navigator.credentials.get({
identity: {
providers: [{
configURL: 'https://idp.example/fedcm.json',
clientId: '123',
}],
},
mediation: 'optional',
});
// In an embedded IdP iframe:
// No user gesture is needed to call this, and the call will be auto-granted.
await document.requestStorageAccess();
// This returns `true`.
const hasAccess = await document.hasStorageAccess();
사용자가 FedCM으로 로그인하면 FedCM 인증이 활성 상태인 한 권한이 자동으로 부여됩니다. 즉, 사용자가 연결 해제되면 권한을 요청할 때 메시지가 표시됩니다.
오리진 트라이얼 참여
Chrome 126 이상에서 Chrome 플래그
chrome://flags#fedcm-authz
를 사용 설정하여 FedCM 연속 API 번들을 로컬에서 사용해 볼 수 있습니다. Chrome 126 이상에서 #fedcm-with-storage-access-api
를 사용 설정하여 FedCM을 로컬에서 Storage Access API의 신뢰 신호로 사용해 볼 수도 있습니다.
이러한 기능은 출처 체험판으로도 사용할 수 있습니다. 오리진 트라이얼을 통해 새로운 기능을 사용해 보고 사용성, 실용성, 효과에 관한 의견을 제공할 수 있습니다. 자세한 내용은 출처 무료 체험판 시작하기를 참고하세요.
FedCM 연속 API 번들 오리진 트라이얼을 사용해 보려면 다음과 같이 두 개의 오리진 트라이얼 토큰을 만듭니다.
- 무료 체험에 등록합니다. 토큰을 IdP 출처에 삽입합니다.
- 서드 파티 일치 체크박스가 선택된 상태로 오리진 트라이얼에 등록합니다. RP의 서드 파티 오리진 트라이얼 등록의 안내에 따라 RP의 토큰을 삽입합니다.
버튼 흐름과 함께 Continuation API를 사용 설정하려면 버튼 모드 API 출처 체험판도 사용 설정하세요.
- 서드 파티로 오리진 트라이얼에 등록합니다. RP용 서드 파티 출처 체험판 등록의 안내에 따라 RP의 토큰을 삽입합니다.
FedCM을 Storage Access API 오리진 트라이얼의 신뢰 신호로 사용해 보려면 다음 단계를 따르세요.
- 오리진 체험판에 등록합니다. 토큰을 IdP 출처에 삽입합니다.
Continuation API 번들 오리진 트라이얼과 Storage Access API 오리진 트라이얼의 신뢰 신호로 사용되는 FedCM은 Chrome 126부터 사용할 수 있습니다.
RP에 서드 파티 오리진 트라이얼 등록
- 출처 무료 체험판 등록 페이지로 이동합니다.
- 등록 버튼을 클릭하고 양식을 작성하여 토큰을 요청합니다.
- IdP의 출처를 웹 출처로 입력합니다.
- 서드 파티 일치를 선택하여 다른 출처에 JavaScript로 토큰을 삽입합니다.
- 제출을 클릭합니다.
- 서드 파티 웹사이트에 발급된 토큰을 삽입합니다.
서드 파티 웹사이트에 토큰을 삽입하려면 IdP의 출처에서 제공되는 IdP의 JavaScript 라이브러리 또는 SDK에 다음 코드를 추가합니다.
const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);
TOKEN_GOES_HERE
을 자체 토큰으로 바꿉니다.