FedCM 업데이트: IdP 로그인 상태 API, 로그인 힌트 등

Chrome 116에는 로그인 힌트 API, 사용자 정보 API, RP 컨텍스트 API와 같은 FedCM 기능이 제공되며 IdP 로그인 상태 API의 오리진 트라이얼이 시작됩니다.

Chrome 116에서는 다음과 같은 세 가지 새로운 Federated Credential Management (FedCM) 기능이 제공됩니다.

  • 로그인 힌트 API: 로그인할 기본 사용자 계정을 지정합니다.
  • User Info API: ID 공급업체 (IdP)가 iframe 내에서 맞춤 로그인 버튼을 렌더링할 수 있도록 재방문 사용자의 정보를 가져옵니다.
  • RP 컨텍스트 API: FedCM 대화상자에서 '로그인'과 다른 제목을 사용합니다.

또한 Chrome은 IdP 로그인 상태 API오리진 트라이얼을 시작합니다. IdP 로그인 상태 API는 필수이며 제공될 때 호환성이 깨지는 변경사항이 됩니다. FedCM의 기존 구현이 있는 경우 오리진 트라이얼에 참여하세요.

Login Hint API

FedCM이 호출되면 브라우저에 지정된 ID 공급업체 (IdP)의 로그인된 계정이 표시됩니다. IdP가 여러 계정을 지원하는 경우 로그인된 모든 계정을 나열합니다.

여러 사용자 계정을 보여주는 FedCM 대화상자
여러 사용자 계정을 보여주는 FedCM 대화상자

사용자가 로그인한 후 신뢰 당사자 (RP)가 사용자에게 재인증을 요청하는 경우가 있습니다. 하지만 사용자는 어떤 계정을 사용하고 있는지 모를 수 있습니다. RP가 로그인할 계정을 지정할 수 있다면 사용자가 계정을 선택하기가 더 쉬워집니다. 로그인 힌트는 Chrome 116에서 제공되며 이를 통해 RP는 목록을 하나로 좁힐 수 있습니다.

이 확장 프로그램은 IdP가 지원하는 모든 가능한 필터 유형과 함께 IdP의 accounts list endpoint 응답에 login_hints 배열을 추가합니다. 예를 들어 IdP가 이메일 및 ID별 필터링을 지원하는 경우 계정 응답은 다음과 같을 수 있습니다.

{
  "accounts": [{
    "id": "demo1",
    "email": "demo1@example.com",
    "name": "John Doe",
    "login_hints": ["demo1", "demo1@example.com"],
    ...
  }, {
    "id": "demo2",
    "email": "demo2@example.com",
    "name": "Jane Doe",
    "login_hints": ["demo2", "demo2@example.com"],
    ...
  }, ...]
}

계정 목록에 login_hints를 전달하면 RP는 다음 코드 샘플에 표시된 대로 loginHint 속성을 사용하여 navigator.credentials.get()를 호출하여 지정된 계정을 선택적으로 표시할 수 있습니다.

return await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: "https://idp.example/manifest.json",
      clientId: "123",
      nonce: nonce,
      loginHint : "demo1@example.com"
    }]
  }
});

User Info API

이제 사용자가 ID 제휴를 통해 로그인할 수 있는 IdP 로고로 장식된 로그인 버튼이 일반적입니다. 하지만 사용자의 프로필 아이콘과 정보를 사용하여 버튼을 꾸미면 특히 사용자가 이전에 IDP로 이 웹사이트에 가입한 경우 로그인하는 것이 훨씬 더 직관적입니다.

Google 계정으로 로그인 버튼
Google로 로그인 버튼
맞춤설정된 Google 계정으로 로그인 버튼
Google 맞춤 로그인 버튼

문제는 맞춤설정된 버튼이 로그인한 사용자를 식별하여 버튼을 렌더링하기 위해 iframe 내 IdP 도메인의 서드 파티 쿠키에 의존하므로 서드 파티 쿠키가 지원 중단되면 사용할 수 없다는 것입니다.

Chrome 116에 제공되는 사용자 정보 API를 사용하면 IdP가 서드 파티 쿠키에 의존하지 않고 서버에서 재방문 사용자의 정보를 가져올 수 있습니다.

API는 RP 웹사이트에 삽입된 iframe 내에서 IdP에 의해 호출되어 사용자 정보를 가져오고 RP 표시의 일부인 것처럼 맞춤설정된 버튼을 렌더링할 수 있습니다. API 호출을 통해 브라우저는 계정 목록 엔드포인트에 요청을 전송한 후 다음 조건이 충족되면 사용자 정보 배열을 반환합니다.

  • 사용자가 이전에 동일한 브라우저 인스턴스에서 FedCM을 통해 IdP로 RP에 로그인했으며 데이터가 삭제되지 않았습니다.
  • 사용자가 동일한 브라우저 인스턴스에서 IdP에 로그인했습니다.
// Iframe displaying a page from the https://idp.example origin
const user_info = await IdentityProvider.getUserInfo({
    configUrl: "https://idp.example/fedcm.json",
    clientId: "client1234"
});

// IdentityProvider.getUserInfo returns an array of user information.
if (user_info.length > 0) {
  // Chrome puts returning accounts first, so the first account received is guaranteed to be a returning account.
  const name = user_info[0].name;
  const given_name = user_info[0].given_name;
  const display_name = given_name ? given_name : name;
  const picture = user_info[0].picture;
  const email = user_info[0].email;
  // Renders the personalized sign-in button with the information above.
}

IdP와 동일한 출처의 iframe 내에서 IdentityProvider.getUserInfo()를 호출하려면 삽입 HTML이 identity-credentials-get 권한 정책을 사용하여 명시적으로 허용해야 합니다.

<iframe src="https://fedcm-demo-idp.dev" allow="identity-credentials-get"></iframe>

https://fedcm-demo-rp.dev/active-mode에서 실제 작동을 확인할 수 있습니다.

RP Context API

Chrome 116에서 제공되는 RP 컨텍스트 API를 사용하면 RP가 사전 정의된 인증 컨텍스트를 수용할 수 있도록 FedCM 대화상자 UI의 문자열을 수정할 수 있습니다. 다양한 옵션은 다음 스크린샷을 참고하세요.

&#39;****에 로그인&#39;으로 렌더링된 FedCM 대화상자
'****에 로그인'으로 렌더링된 FedCM 대화상자입니다. RP 컨텍스트가 지정되지 않은 경우 기본 옵션입니다.
다음과 같이 렌더링된 FedCM 대화상자
'****에 가입'으로 렌더링된 FedCM 대화상자
다음과 같이 렌더링된 FedCM 대화상자
'****로 계속'으로 렌더링된 FedCM 대화상자
&#39;**** 사용&#39;으로 렌더링된 FedCM 대화상자
'**** 사용'으로 렌더링된 FedCM 대화상자

사용법은 간단합니다. "signin"(기본값), "signup", "use" 또는 "continue" 중 하나를 identity.context 속성에 제공합니다.

const credential = await navigator.credentials.get({
  identity: {
    // "signin" is the default, "signup", "use" and "continue" 
    // can also be used
    context: "signup", 
    providers: [{
      configURL: "https://idp.example/fedcm.json",
      clientId: "1234",
    }],
  }
});

IdP 로그인 상태 API 오리진 트라이얼

Chrome은 Chrome 116부터 데스크톱에서 IdP 로그인 상태 API 오리진 트라이얼을 시작하고 나중에 Android Chrome에서도 시작합니다. 오리진 트라이얼을 사용하면 새로운 기능 또는 실험용 기능에 액세스하여 기능이 모든 사용자에게 제공되기 전에 사용자가 한정 기간 동안 사용해 볼 수 있는 기능을 빌드할 수 있습니다.

IdP 로그인 상태 API는 IdP가 브라우저에 IdP의 사용자 로그인 상태를 알리는 메커니즘입니다. 이 API를 사용하면 브라우저가 IdP에 대한 불필요한 요청을 줄이고 잠재적인 타이밍 공격을 완화할 수 있습니다.

브라우저에 사용자의 로그인 상태 알림

사용자가 IdP에 로그인되어 있거나 모든 IdP 계정에서 로그아웃된 경우 IdP는 HTTP 헤더를 전송하거나 JavaScript API를 호출하여 사용자의 로그인 상태를 브라우저에 알릴 수 있습니다. 브라우저는 상태를 'sign-in', 'sign-out' 또는 'unknown' (기본값) 중 하나로 기록합니다.

사용자가 로그인했음을 알리려면 최상위 탐색 또는 동일 출처 하위 리소스 요청에서 IdP-SignIn-Status: action=signin HTTP 헤더를 전송하세요.

IdP-SignIn-Status: action=signin

또는 IdP 출처에서 JavaScript API IdentityProvider.login()를 호출합니다.

IdentityProvider.login()

이렇게 하면 사용자의 로그인 상태가 '로그인'으로 기록됩니다. 사용자의 로그인 상태가 '로그인'으로 설정되면 FedCM을 호출하는 PR이 IdP의 계정 목록 엔드포인트에 요청을 보내고 FedCM 대화상자에 사용 가능한 계정을 사용자에게 표시합니다.

사용자가 모든 계정에서 로그아웃했음을 알리려면 최상위 탐색 또는 동일 출처 하위 리소스 요청에서 IdP-SignIn-Status: action=signout-all HTTP 헤더를 전송합니다.

IdP-SignIn-Status: action=signout-all

또는 IdP 출처에서 JavaScript API IdentityProvider.logout()를 호출합니다.

IdentityProvider.logout()

이렇게 하면 사용자의 로그인 상태가 '로그아웃'으로 기록됩니다. 사용자의 로그인 상태가 '로그아웃'인 경우 IdP의 계정 목록 엔드포인트에 요청하지 않고 FedCM 호출이 자동으로 실패합니다.

기본적으로 IdP 로그인 상태는 '알 수 없음'으로 설정됩니다. 이 상태는 IdP가 IdP 로그인 상태 API를 사용하여 신호를 보내기 전에 사용됩니다. 이 상태는 더 나은 전환을 위해 도입되었습니다. 이 API가 제공될 때 사용자가 이미 IdP에 로그인했을 수 있으며 FedCM이 처음 호출될 때 IdP가 브라우저에 이를 알릴 기회가 없을 수 있기 때문입니다. 이 경우 IdP의 계정 목록 엔드포인트에 요청을 보내고 계정 목록 엔드포인트의 응답에 따라 상태를 업데이트합니다.

  • 엔드포인트가 활성 계정 목록을 반환하면 상태를 '로그인'으로 업데이트하고 FedCM 대화상자를 열어 해당 계정을 표시합니다.
  • 엔드포인트가 계정을 반환하지 않으면 상태를 '로그아웃'으로 업데이트하고 FedCM 호출을 실패합니다.

사용자 세션이 만료되면 어떻게 되나요? 사용자가 동적 로그인 흐름을 통해 로그인하도록 허용

IdP가 브라우저에 사용자의 로그인 상태를 계속 알리더라도 세션이 만료되는 등의 경우 동기화되지 않을 수 있습니다. 브라우저가 로그인 상태가 '로그인'일 때 사용자 인증 정보가 있는 요청을 계정 목록 엔드포인트로 보내려고 하지만 세션을 더 이상 사용할 수 없으므로 서버에서 거부합니다. 이러한 시나리오에서 브라우저는 팝업 창을 통해 사용자가 IdP에 로그인하도록 동적으로 허용할 수 있습니다.

FedCM 대화상자에는 다음 이미지와 같이 메시지가 표시됩니다.

IdP에 로그인하도록 제안하는 FedCM 대화상자
IdP에 로그인하도록 제안하는 FedCM 대화상자

계속 버튼을 클릭하면 브라우저에서 팝업 창을 열어 사용자를 IdP의 로그인 페이지로 보냅니다.

IdP에 로그인 버튼을 클릭한 후 표시되는 팝업 창
IdP에 로그인 버튼을 클릭한 후 표시되는 팝업 창입니다.

로그인 페이지 URL (IdP의 출처여야 함)은 IdP 구성 파일의 일부로 signin_url를 사용하여 지정할 수 있습니다.

{
  "accounts_endpoint": "/auth/accounts",
  "client_metadata_endpoint": "/auth/metadata",
  "id_assertion_endpoint": "/auth/idtokens",
  "signin_url": "/signin"
  }
}

팝업 창은 퍼스트 파티 쿠키를 사용하는 일반 브라우저 창입니다. 콘텐츠 창 내에서 발생하는 일은 IdP에 달려 있지만 RP 페이지에 크로스 오리진 통신 요청을 할 수 있는 창 핸들은 없습니다. 사용자가 로그인한 후 IdP는 다음을 수행해야 합니다.

  • IdP-SignIn-Status: action=signin 헤더를 보내거나 IdentityProvider.login() API를 호출하여 사용자 로그인 여부를 브라우저에 알립니다.
  • IdentityProvider.close()를 호출하여 자체 (팝업 창)를 닫습니다.
// User is signed in...
// Don't forget feature detection.
if (IdentityProvider) {
  // Signal to the browser that the user has signed in.
  IdentityProvider.close();
}
사용자가 FedCM을 사용하여 IdP에 로그인한 후 RP에 로그인합니다.

데모에서 IdP 로그인 상태 API 동작을 사용해 볼 수 있습니다. 데모 IdP에 로그인한 후 3분이 지나면 세션이 만료됩니다. 그런 다음 팝업 창 동작을 통해 IdP에 로그인하는 것을 확인할 수 있습니다.

오리진 트라이얼 참여

Chrome 116 이상에서 Chrome
플래그
chrome://flags#fedcm-idp-signin-status-api를 사용 설정하여
IdP 로그인 상태 API를 로컬로 사용해 볼 수 있습니다.

오리진 트라이얼을 두 번 등록하여 IdP 로그인 상태 API를 사용 설정할 수도 있습니다.

오리진 트라이얼을 통해 새로운 기능을 사용해 보고 웹 표준 커뮤니티에 유용성, 실용성, 효과에 관한 의견을 제공할 수 있습니다. 자세한 내용은 웹 개발자를 위한 오리진 트라이얼 가이드를 참고하세요.

IdP Sign-In Status API 오리진 트라이얼은 Chrome 116부터 Chrome 119까지 사용할 수 있습니다.

IdP의 오리진 트라이얼 등록

  1. 오리진 트라이얼 등록 페이지로 이동합니다.
  2. 등록 버튼을 클릭하고 양식을 작성하여 토큰을 요청합니다.
  3. IdP의 출처를 웹 출처로 입력합니다.
  4. 제출을 클릭합니다.
  5. IdentityProvider.close()를 사용하는 페이지의 헤드에 origin-trial <meta> 태그를 추가합니다. 예를 들어 다음과 같이 표시될 수 있습니다.
    <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">

RP의 서드 파티 오리진 트라이얼 등록

  1. 오리진 트라이얼 등록 페이지로 이동합니다.
  2. 등록 버튼을 클릭하고 양식을 작성하여 토큰을 요청합니다.
  3. IdP의 출처를 웹 출처로 입력합니다.
  4. 다른 출처에서 JavaScript로 토큰을 삽입하려면 서드 파티 매칭을 선택합니다.
  5. 제출을 클릭합니다.
  6. 발급된 토큰을 서드 파티 웹사이트에 삽입합니다.

서드 파티 웹사이트에 토큰을 삽입하려면 IdP의 출처에서 제공되는 JavaScript 라이브러리 또는 SDK에 다음 코드를 추가하세요.

const tokenElement = document.createElement('meta');
tokenElement.httpEquiv = 'origin-trial';
tokenElement.content = 'TOKEN_GOES_HERE';
document.head.appendChild(tokenElement);

TOKEN_GOES_HERE을 고유한 토큰으로 바꿉니다.

참여 및 의견 공유

테스트 중에 의견이 있거나 문제가 발생하면 crbug.com에서 공유할 수 있습니다.

사진: 댄 크리스티안 파두레트(Unsplash 제공)