FedCM 업데이트: Login Status API, Error API, Auto-selected Flag API

Chrome 120에서는 FedCM용 Login Status API를 제공합니다. Login Status API (이전 명칭: IdP Sign-in Status API)를 사용하면 웹사이트, 특히 ID 공급업체가 사용자가 로그인하거나 로그아웃할 때 브라우저에 신호를 보낼 수 있습니다. 이 신호는 FedCM에서 무음 타이밍 공격 문제를 해결하는 데 사용되며, 이를 통해 FedCM이 서드 파티 쿠키 없이 완전히 작동할 수 있습니다. 이 업데이트는 이전에 작업 범위의 일환으로 FedCM의 원래 출시 인텐트에서 식별한 이전 버전과 호환되지 않는 마지막으로 남아 있는 변경사항을 해결합니다.

Login Status API는 개인 정보 보호 속성과 사용성을 개선하지만 출시된 후에는 이전 버전과 호환되지 않는 변경사항입니다. 기존에 FedCM이 구현되어 있다면 다음 안내에 따라 업데이트하세요.

또한 Chrome에서는 다음과 같은 두 가지 새로운 제휴 사용자 인증 정보 관리(FedCM) 기능을 제공합니다.

  • 오류 API: ID 어설션 엔드포인트의 서버 응답(있는 경우)을 기반으로 네이티브 UI를 사용하여 로그인 시도가 실패하면 사용자에게 알립니다.
  • 자동 선택 플래그 API: 흐름에서 사용자 인증 정보가 자동으로 선택된 경우 ID 공급자 (IdP) 및 신뢰 당사자 (RP)에 알립니다.

Login Status API

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

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

IdP는 사용자가 IdP에 로그인했거나 모든 IdP 계정에서 로그아웃했을 때 HTTP 헤더를 전송하거나 JavaScript API를 호출하여 사용자의 로그인 상태를 브라우저에 전달할 수 있습니다. 브라우저는 구성 URL로 식별되는 각 IdP에 대해 로그인 상태를 나타내는 3-상태 변수를 유지하며, 가능한 값은 logged-in, logged-out, unknown입니다. 기본 상태는 unknown입니다.

사용자가 로그인했음을 알리려면 최상위 탐색 또는 동일 출처 하위 리소스 요청에서 Set-Login: logged-in HTTP 헤더를 전송합니다.

Set-Login: logged-in

또는 IdP 출처에서 JavaScript API navigator.login.setStatus('logged-in')를 호출합니다.

navigator.login.setStatus('logged-in');

이러한 호출은 사용자의 로그인 상태를 logged-in로 기록합니다. 사용자의 로그인 상태가 logged-in로 설정되면 FedCM을 호출하는 RP가 IdP의 계정 목록 엔드포인트에 요청을 전송하고 FedCM 대화상자에 사용 가능한 계정을 사용자에게 표시합니다.

사용자가 모든 계정에서 로그아웃되었음을 알리려면 최상위 탐색 또는 동일 출처 하위 리소스 요청에서 Set-Login: logged-out HTTP 헤더를 전송합니다.

Set-Login: logged-out

또는 IdP 출처에서 JavaScript API navigator.login.setStatus('logged-out')를 호출합니다.

navigator.login.setStatus('logged-out');

이러한 호출은 사용자의 로그인 상태를 logged-out로 기록합니다. 사용자의 로그인 상태가 logged-out인 경우 IdP의 계정 목록 엔드포인트에 요청하지 않고도 FedCM 호출이 자동으로 실패합니다.

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

  • 엔드포인트가 활성 계정 목록을 반환하면 상태를 logged-in로 업데이트하고 FedCM 대화상자를 열어 해당 계정을 표시합니다.
  • 엔드포인트에서 계정을 반환하지 않으면 상태를 logged-out로 업데이트하고 FedCM 호출을 실패로 처리합니다.

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

IdP가 계속해서 브라우저에 사용자의 로그인 상태를 알리더라도 세션이 만료되는 경우와 같이 상태가 동기화되지 않을 수 있습니다. 로그인 상태가 logged-in인 경우 브라우저는 계정 목록 엔드포인트에 사용자 인증 정보가 포함된 요청을 전송하려고 시도하지만 세션을 더 이상 사용할 수 없으므로 서버는 계정을 반환하지 않습니다. 이러한 시나리오에서 브라우저는 대화상자 창을 통해 사용자가 IdP에 동적으로 로그인하도록 허용할 수 있습니다.

FedCM 대화상자에는 다음 이미지와 같이 로그인을 제안하는 메시지가 표시됩니다.

IdP에 로그인하라는 메시지가 표시된 FedCM 대화상자
IdP에 로그인하라는 제안을 하는 FedCM 대화상자

사용자가 계속 버튼을 클릭하면 브라우저에서 IdP 로그인 페이지의 대화상자를 엽니다.

대화상자 예
IdP에 로그인 버튼을 클릭한 후 표시되는 대화상자의 예시입니다.

로그인 페이지 URL은 IdP 구성 파일의 일부로 login_url로 지정됩니다.

{
  "accounts_endpoint": "/auth/accounts",
  "client_metadata_endpoint": "/auth/metadata",
  "id_assertion_endpoint": "/auth/idtokens",
  "login_url": "/login"
  }
}

대화상자는 퍼스트 파티 쿠키가 있는 일반 브라우저 창입니다. 대화상자 내에서 발생하는 모든 상황은 IdP에 따라 다르며, RP 페이지에 교차 출처 통신 요청을 할 수 있는 창 핸들은 없습니다. 사용자가 로그인하면 IdP는 다음을 실행해야 합니다.

  • Set-Login: logged-in 헤더를 전송하거나 navigator.login.setStatus("logged-in") API를 호출하여 사용자가 로그인했음을 브라우저에 알립니다.
  • IdentityProvider.close()를 호출하여 대화상자를 닫습니다.
사용자가 FedCM을 사용하여 IdP에 로그인한 후 RP에 로그인합니다.
사용자가 FedCM을 사용하여 IdP에 로그인한 후 RP에 로그인합니다.

데모에서 Login Status API 동작을 사용해 볼 수 있습니다.

  1. IdP로 이동하여 로그인 버튼을 탭합니다.
  2. 임의의 계정으로 로그인합니다.
  3. 계정 상태 드롭다운에서 세션 만료됨을 선택합니다.
  4. 개인 정보 업데이트 버튼을 누릅니다.
  5. RP를 방문하여 FedCM 사용해 보기 버튼을 탭합니다.

모듈 동작을 통해 IdP에 대한 로그인을 관찰할 수 있어야 합니다.

Error API

Chrome이 ID 어설션 엔드포인트에 요청을 전송하는 경우 (예: 사용자가 FedCM UI에서 계속 버튼을 클릭하거나 자동 재인증이 트리거되는 경우) IdP가 합법적인 이유로 토큰을 발급하지 못할 수 있습니다. 예를 들어 클라이언트가 승인되지 않았거나 서버를 일시적으로 사용할 수 없는 경우 등이 여기에 해당합니다. 현재 Chrome은 이러한 오류가 발생하면 요청을 자동으로 실패시키고 프로미스를 거부하여 RP에만 알립니다.

Chrome은 Error API를 사용하여 IdP에서 제공한 오류 정보가 포함된 네이티브 UI를 표시하여 사용자에게 알립니다.

사용자가 로그인 시도에 실패한 후 오류 메시지를 보여주는 FedCM 대화상자 이 문자열은 오류 유형과 연결됩니다.
사용자의 로그인 시도가 실패한 후 오류 메시지를 보여주는 FedCM 대화상자입니다. 이 문자열은 오류 유형과 연결됩니다.

IdP HTTP API

id_assertion_endpoint 응답에서 IdP는 요청 시 토큰을 발급할 수 있는 경우 브라우저에 토큰을 반환할 수 있습니다. 이 제안서에서 토큰을 발급할 수 없는 경우 IdP는 두 가지 새로운 선택적 필드가 있는 'error' 응답을 반환할 수 있습니다.

  1. code
  2. url
// id_assertion_endpoint response
{
  "error": {
     "code": "access_denied",
     "url": "https://idp.example/error?type=access_denied"
  }
}

코드의 경우 IdP는 OAuth 2.0 지정 오류 목록[invalid_request, unauthorized_client, access_denied, server_error, temporarily_unavailable] 에서 알려진 오류 중 하나를 선택하거나 임의의 문자열을 사용할 수 있습니다. 후자인 경우 Chrome은 일반 오류 메시지로 오류 UI를 렌더링하고 코드를 RP에 전달합니다.

url의 경우 사용자에게 오류에 관한 추가 정보를 제공하기 위해 오류에 관한 정보가 포함된 사람이 읽을 수 있는 웹페이지를 식별합니다. 브라우저는 네이티브 UI에서 풍부한 오류 메시지를 제공할 수 없으므로 이 필드는 사용자에게 유용합니다. 예를 들어 다음 단계 링크, 고객 서비스 연락처 정보 등이 여기에 해당합니다. 사용자가 오류 세부정보와 해결 방법을 자세히 알아보려면 브라우저 UI에서 제공된 페이지를 방문하면 됩니다. URL은 IdP configURL와 동일한 사이트여야 합니다.

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;
}

Auto-Selected Flag API

mediation: optional는 인증 관리 API의 기본 사용자 미디에이션 동작이며 가능한 경우 자동 재인증을 트리거합니다. 하지만 자동 재인증은 브라우저만 알 수 있는 이유로 사용할 수 없을 수 있습니다. 사용할 수 없는 경우 사용자에게 명시적 사용자 미디에이션으로 로그인하라는 메시지가 표시될 수 있습니다. 명시적 사용자 미디에이션은 속성이 다른 흐름입니다.

  • API 호출자의 관점에서 ID 토큰을 수신할 때 자동 재인증 흐름의 결과인지 여부를 알 수 없습니다. 따라서 API 성능을 평가하고 그에 따라 UX를 개선하기가 어렵습니다.
  • IdP의 관점에서도 실적 평가를 위해 자동 재인증이 발생했는지 여부를 알 수 없습니다. 또한 명시적 사용자 미디에이션이 사용되었는지 여부에 따라 더 많은 보안 관련 기능을 지원하는 데 도움이 될 수 있습니다. 예를 들어 인증 시 명시적인 사용자 중재가 필요한 더 높은 보안 등급을 선호하는 사용자도 있습니다. IDP가 이러한 미디에이션 없이 토큰 요청을 수신하면 요청을 다르게 처리할 수 있습니다. 예를 들어 RP가 mediation: required를 사용하여 FedCM API를 다시 호출할 수 있도록 오류 코드를 반환합니다.

따라서 자동 재인증 흐름을 표시하면 개발자에게 도움이 됩니다.

Chrome은 자동 선택 플래그 API를 사용하여 자동 재인증이 발생하거나 명시적 미디에이션이 발생할 때마다 IdP와 RP 모두에 계속 버튼을 탭하여 명시적 사용자 권한을 획득했는지 공유합니다. 공유는 IdP/RP 통신에 대한 사용자 권한이 부여된 후에만 이루어집니다.

IdP 공유

사용자 권한 부여 후 IdP에 정보를 공유하기 위해 Chrome은 id_assertion_endpoint에 전송된 POST 요청에 is_auto_selected=true를 포함합니다.

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=Ct0D&disclosure_text_shown=true&is_auto_selected=true

RP 공유

브라우저는 IdentityCredential를 통해 isAutoSelected의 RP에 정보를 공유할 수 있습니다.

const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://idp.example/manifest.json',
      clientId: '1234'
    }]
  }
});

if (cred.isAutoSelected !== undefined) {
  const isAutoSelected = cred.isAutoSelected;
}

참여 및 의견 공유

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

Unsplash빨간 모자 소녀 사진