Wdrażanie rozwiązania do obsługi tożsamości z użyciem FedCM po stronie dostawcy tożsamości

Wdrożenie FedCM obejmuje kilka podstawowych kroków zarówno w przypadku dostawcy tożsamości, jak i strony zależnej. Więcej informacji o tym, jak wdrożyć FedCM po stronie RP, znajdziesz w dokumentacji.

Aby wdrożyć FedCM, IdPs muszą wykonać te czynności:

Tworzenie pliku well-known

Aby zapobiec nadużywaniu interfejsu API przez moduły śledzące, plik .well-known musi być udostępniany z /.well-known/web-identity domeny eTLD+1 dostawcy tożsamości.

Znany plik może zawierać te właściwości:

Właściwość Wymagane Opis
provider_urls wymagane Tablica ścieżek do plików konfiguracji dostawcy tożsamości. Ignorowany (ale nadal wymagany), jeśli określono parametry accounts_endpointlogin_url.
accounts_endpoint zalecane, wymaga login_url
Adres URL punktu końcowego kont. Umożliwia to obsługę wielu konfiguracji, o ile każdy plik konfiguracyjny używa tego samego adresu URL login_urlaccounts_endpoint.

Uwaga: ten parametr jest obsługiwany od Chrome 132.
login_url zalecane, wymaga accounts_endpoint Adres URL strony logowania, na której użytkownik loguje się u dostawcy tożsamości. Umożliwia to obsługę wielu konfiguracji, o ile każdy plik konfiguracyjny używa tych samych wartości login_urlaccounts_endpoint.

Uwaga: ten parametr jest obsługiwany w Chrome 132 i nowszych wersjach.

Jeśli na przykład punkty końcowe dostawcy tożsamości są obsługiwane w domenie https://accounts.idp.example/, muszą one obsługiwać plik well-known w domenie https://idp.example/.well-known/web-identity, a także plik konfiguracji dostawcy tożsamości. Oto przykład zawartości dobrze znanego pliku:

  {
    "provider_urls": ["https://accounts.idp.example/config.json"]
  }

Dostawcy tożsamości mogą obsługiwać wiele plików konfiguracyjnych, określając w pliku .well-known wartości accounts_endpointlogin_url. Ta funkcja może być przydatna w tych przypadkach:

  • Dostawca tożsamości musi obsługiwać wiele różnych konfiguracji testowych i produkcyjnych.
  • Dostawca tożsamości musi obsługiwać różne konfiguracje w poszczególnych regionach (np.eu-idp.exampleus-idp.example).

Aby obsługiwać wiele konfiguracji (np. rozróżniać środowisko testowe i produkcyjne), dostawca tożsamości musi określić accounts_endpoint i 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"
  }

Tworzenie pliku konfiguracji dostawcy tożsamości i punktów końcowych

Plik konfiguracji dostawcy tożsamości zawiera listę wymaganych punktów końcowych dla przeglądarki. Dostawcy tożsamości muszą hostować co najmniej 1 plik konfiguracyjny oraz wymagane punkty końcowe i adresy URL. Wszystkie odpowiedzi JSON muszą być przekazywane z typem treści application/json.

Adres URL pliku konfiguracyjnego jest określany przez wartości podane w wywołaniu navigator.credentials.get() wykonanym na RP. Dostawca usług przekaże adres URL pliku konfiguracyjnego dla każdego dostawcy tożsamości:

  // Executed on RP's side:
  try {
    const credential = await navigator.credentials.get({
      identity: {
        providers: [
          {
            // To allow users to sign in with the IdP1 using FedCM, RP specifies the IdP's config file URL:
            configUrl: 'https://idp1.example/foo.json', // first IdP
            clientId: '123',
          },
          // To allow users to sign in with the IdP2 using FedCM, RP specifies the IdP's config file URL.
          // Note that multiple IdPs in a single get() are supported from Chrome 136.
          {
            configUrl: 'https://idp2.example/bar.json', // second IdP
            clientId: '456',
          },
        ],
      },
    });

    const token = credential.token;
    // Get the current IdP's configURL to identify which provider the user is signed in with
    const currentIdpConfigUrl = credential.configURL;
    if (currentIdpConfigUrl === 'https://idp1.example/foo.json') {
      // handle the case where the user signed in with idp1
    } else if (currentIdpConfigUrl === 'https://idp2.example/bar.json') {
      // handle the case where the user signed in with idp2
    }
  } catch (error) {
    // handle error
  }

Przeglądarka pobierze plik konfiguracyjny za pomocą żądania GET bez nagłówka Origin ani nagłówka Referer. Żądanie nie zawiera plików cookie i nie przekierowuje. Skutecznie uniemożliwia to dostawcy tożsamości dowiedzenie się, kto wysłał żądanie i która usługa RP próbuje się połączyć. Na przykład:

  GET /config.json HTTP/1.1
  Host: accounts.idp.example
  Accept: application/json
  Sec-Fetch-Dest: webidentity

Dostawca tożsamości musi zaimplementować punkt końcowy konfiguracji, który odpowiada w formacie JSON. Plik JSON zawiera te właściwości:

Właściwość Opis
accounts_endpoint (wymagane) Adres URL punktu końcowego kont.
account_label (opcjonalnie) Ciąg tekstowy niestandardowej etykiety konta określający, które konta mają być zwracane, gdy używany jest ten plik konfiguracyjny, np. "account_label": "developer".
Dostawca tożsamości może wdrożyć niestandardowe etykietowanie kont w ten sposób:

Na przykład dostawca tożsamości wdraża "https://idp.example/developer-config.json" plik konfiguracyjny z określonym parametrem "account_label": "developer". Dostawca tożsamości oznacza też niektóre konta etykietą "developer" za pomocą parametru label_hintspunkcie końcowym kont. Gdy dostawca tożsamości wywoła navigator.credentials.get() z określonym plikiem konfiguracyjnym "https://idp.example/developer-config.json", zostaną zwrócone tylko konta z etykietą "developer".

Uwaga: niestandardowe etykiety kont są obsługiwane od Chrome 132.
supports_use_other_account (opcjonalnie) Wartość logiczna określająca, czy użytkownik może zalogować się na konto inne niż to, na którym jest obecnie zalogowany (jeśli dostawca tożsamości obsługuje wiele kont). Dotyczy to tylko trybu aktywnego.
client_metadata_endpoint (opcjonalnie) Adres URL punktu końcowego metadanych klienta.
id_assertion_endpoint (wymagane) Adres URL punktu końcowego potwierdzenia tożsamości.
disconnect (opcjonalnie) Adres URL punktu końcowego odłączania.
login_url (wymagane) Adres URL strony logowania, na której użytkownik loguje się u dostawcy tożsamości.
branding (opcjonalnie) Obiekt zawierający różne opcje brandingu.
branding.background_color (opcjonalnie) Opcja brandingu, która ustawia kolor tła przycisku „Kontynuuj jako...”. Użyj odpowiedniej składni CSS, czyli hex-color, hsl(), rgb() lub named-color.
branding.color (opcjonalnie) Opcja brandingu, która ustawia kolor tekstu przycisku „Kontynuuj jako…”. Użyj odpowiedniej składni CSS, czyli hex-color, hsl(), rgb() lub named-color.
branding.icons (opcjonalnie) Tablica obiektów ikon. Te ikony są wyświetlane w oknie logowania. Obiekt ikony ma 2 parametry:
  • url (wymagany): adres URL obrazu ikony. Nie obsługuje obrazów SVG.
  • size (opcjonalnie): wymiary ikony, które aplikacja uznaje za kwadratowe i o jednej rozdzielczości. W trybie pasywnym musi być większa lub równa 25 pikselom, a w trybie aktywnym – większa lub równa 40 pikselom.

Oto przykładowa treść odpowiedzi od dostawcy tożsamości:

  {
    "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.
    "account_label": "developer",
    "supports_use_other_account": true,
    "branding": {
      "background_color": "green",
      "color": "#FFEEAA",
      "icons": [{
        "url": "https://idp.example/icon.ico",
        "size": 25
      }]
    }
  }

Gdy przeglądarka pobierze plik konfiguracyjny, wysyła kolejne żądania do punktów końcowych dostawcy tożsamości:

Punkty końcowe dostawcy tożsamości
Punkty końcowe dostawcy tożsamości

Użyj innego konta

Użytkownicy mogą przełączyć się na konto inne niż to, na którym są obecnie zalogowani, jeśli dostawca tożsamości obsługuje wiele kont lub zastępowanie istniejącego konta.

Aby umożliwić użytkownikowi wybór innych kont, dostawca tożsamości musi określić tę funkcję w pliku konfiguracyjnym:

  {
    "accounts_endpoint" : "/accounts.example",
    "supports_use_other_account": true
  }

Punkt końcowy kont

Punkt końcowy kont dostawcy tożsamości zwraca listę kont, na których użytkownik jest zalogowany u dostawcy tożsamości. Jeśli dostawca tożsamości obsługuje wiele kont, ten punkt końcowy zwróci wszystkie zalogowane konta.

Przeglądarka wysyła żądanie GET z plikami cookie z atrybutem SameSite=None, ale bez parametru client_id, nagłówka Origin ani nagłówka Referer. Dzięki temu dostawca tożsamości nie może dowiedzieć się, w której usłudze użytkownik próbuje się zalogować. Na przykład:

  GET /accounts.example HTTP/1.1
  Host: accounts.idp.example
  Accept: application/json
  Cookie: 0x23223
  Sec-Fetch-Dest: webidentity

Po otrzymaniu żądania serwer powinien:

  1. Sprawdź, czy żądanie zawiera nagłówek HTTP Sec-Fetch-Dest: webidentity.
  2. Dopasuj pliki cookie sesji do identyfikatorów kont, na które użytkownik jest już zalogowany.
  3. Odpowiedz listą kont.

Przeglądarka oczekuje odpowiedzi w formacie JSON, która zawiera właściwość accounts z tablicą informacji o kontach z tymi właściwościami:

Właściwość Opis
id (wymagane) Unikalny identyfikator użytkownika.
name Imię i nazwisko użytkownika zgodnie z jego ustawieniami regionalnymi i preferencjami.

Uwaga: od Chrome 141 wymagany jest co najmniej jeden z parametrów name, email, username lub tel. W starszych wersjach Chrome wymagane są oba te elementy: nameemail.
username Nazwa użytkownika wybrana przez użytkownika.

Uwaga: od Chrome 141 wymagany jest co najmniej jeden z parametrów name, email, username lub tel.
email Adres e-mail użytkownika.

Uwaga: od Chrome 141 wymagany jest co najmniej jeden z parametrów name, email, username lub tel. W starszych wersjach Chrome wymagane są oba te elementy: nameemail.
tel Numer telefonu użytkownika.

Uwaga: od Chrome 141 wymagany jest co najmniej jeden z parametrów name, email, username lub tel.
picture (opcjonalnie) Adres URL obrazu awatara użytkownika.
given_name (opcjonalnie) Imię użytkownika.
approved_clients (opcjonalnie) Tablica identyfikatorów klientów RP, z którymi użytkownik jest zarejestrowany.
login_hints (opcjonalnie) Tablica wszystkich możliwych typów filtrów, które dostawca tożsamości obsługuje w celu określenia konta. Dostawca tożsamości może wywołać navigator.credentials.get() z właściwością loginHint, aby selektywnie wyświetlać określone konto.
domain_hints (opcjonalnie) Tablica wszystkich domen powiązanych z kontem. RP może wywołać funkcję navigator.credentials.get() z właściwością domainHint, aby filtrować konta.
label_hints (opcjonalnie) Tablica ciągów znaków z niestandardowymi etykietami konta, z którymi jest powiązane konto.
Dostawca tożsamości może wdrożyć niestandardowe etykietowanie kont w ten sposób:
  • Określ etykiety kont w punkcie końcowym kont (za pomocą tego parametru label_hints).
  • Utwórz plik konfiguracyjny dla każdej etykiety.

Na przykład dostawca tożsamości implementuje https://idp.example/developer-config.json plik konfiguracyjny z określonym parametrem "account_label": "developer". Dostawca tożsamości oznacza też niektóre konta etykietą "developer" za pomocą parametru label_hints punkcie końcowym kont. Gdy dostawca tożsamości wywoła navigator.credentials.get() z określonym plikiem konfiguracyjnym https://idp.example/developer-config.json, zwracane będą tylko konta z etykietą "developer".

Niestandardowe etykiety kont różnią się od podpowiedzi logowania i podpowiedzi domeny tym, że są w pełni obsługiwane przez serwer dostawcy tożsamości, a strona ufająca określa tylko plik konfiguracyjny do użycia.

Uwaga: niestandardowe etykiety kont są obsługiwane od Chrome 132.

Przykładowa treść odpowiedzi:

  {
    "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.
      "label_hints": ["enterprise", "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"]
    }]
  }

Jeśli użytkownik nie jest zalogowany, odpowiedz kodem HTTP 401 (Nieautoryzowany).

Lista zwróconych kont jest wykorzystywana przez przeglądarkę i nie będzie dostępna dla dostawcy tożsamości.

Punkt końcowy potwierdzenia tożsamości

Punkt końcowy potwierdzenia tożsamości dostawcy tożsamości zwraca potwierdzenie dla zalogowanego użytkownika. Gdy użytkownik loguje się w witrynie RP za pomocą navigator.credentials.get()wywołania, przeglądarka wysyła żądanie POST z plikami cookie z wartością SameSite=None i typem treści application/x-www-form-urlencoded do tego punktu końcowego z tymi informacjami:

Właściwość Opis
client_id (wymagane) Identyfikator klienta RP.
account_id (wymagane) Unikalny identyfikator logującego się użytkownika.
disclosure_text_shown Zwraca ciąg znaków "true" lub "false" (zamiast wartości logicznej). W tych przypadkach wynikiem jest "false":
  • Jeśli tekst informacji nie został wyświetlony, ponieważ identyfikator klienta dostawcy usług został uwzględniony na approved_clients liście właściwości w odpowiedzi z punktu końcowego kont.
  • Jeśli tekst informacji nie został wyświetlony, ponieważ przeglądarka zarejestrowała w przeszłości moment rejestracji bez obecności approved_clients.
  • Jeśli parametr fields nie zawiera wszystkich 3 pól („name”, „email” i „picture”), np. fields=[ ] lub fields=['name', 'picture']. Jest to wymagane w przypadku zgodności wstecznej ze starszymi implementacjami.

    Uwaga: od wersji Chrome 141 tekst informacyjny może być wyświetlany nawet wtedy, gdy wartość disclosure_text_shown to "false". Aby sprawdzić, czy tekst z informacją został wyświetlony, sprawdź wartość disclosure_shown_for.
disclosure_shown_for Zawiera listę pól, które przeglądarka wyświetliła użytkownikowi w tekście informacji, aby powiadomić go, o jakie dane dostawca tożsamości prosi dostawcę usług.
is_auto_selected Jeśli na RP przeprowadzana jest automatyczna ponowna weryfikacja, is_auto_selected oznacza "true". W przeciwnym razie "false". Jest to przydatne w przypadku funkcji związanych z bezpieczeństwem. Niektórzy użytkownicy mogą na przykład preferować wyższy poziom bezpieczeństwa, który wymaga wyraźnego udziału użytkownika w uwierzytelnianiu. Jeśli dostawca tożsamości otrzyma prośbę o token bez takiego pośrednictwa, może ją obsłużyć w inny sposób. Na przykład zwróć kod błędu, aby dostawca tożsamości mógł ponownie wywołać interfejs FedCM API z parametrem mediation: required.
fields (opcjonalnie) Tablica ciągów znaków określająca informacje o użytkowniku, o które RP poprosił dostawcę tożsamości. Możesz opcjonalnie określić te pola:
  • "name"
  • "username"
  • "email"
  • "tel"
  • "picture"
Przeglądarka wyśle parametry fields, disclosure_text_showndisclosure_shown_for z określonymi polami w żądaniu POST, jak w poniższym przykładzie.

Uwaga: interfejs Fields API jest obsługiwany przez Chrome 132 i nowsze wersje. Pola `"username"` i `"tel"` są obsługiwane od Chrome 141.
params (opcjonalnie) Dowolny prawidłowy obiekt JSON, który umożliwia określenie dodatkowych niestandardowych parametrów klucz-wartość, np.:
  • scope: wartość ciągu znaków zawierająca dodatkowe uprawnienia, o które musi poprosić dostawca tożsamości, np. "drive.readonly calendar.readonly"
  • nonce: losowy ciąg znaków podany przez dostawcę tożsamości, aby mieć pewność, że odpowiedź została wydana w odpowiedzi na to konkretne żądanie. Zapobiega atakom typu replay.
  • Inne niestandardowe parametry pary klucz-wartość.
Gdy przeglądarka wyśle żądanie POST, wartość params zostanie zserializowana do formatu JSON, a następnie zakodowana w procentach.

Uwaga: interfejs Parameters API jest obsługiwany przez Chrome w wersji 132 i nowszych.

Przykład nagłówka 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&params=%22%7B%5C%22nonce%5C%22%3A%5C%22nonce-value%5C%22%7D%22.%0D%0A4&fields=email,picture&disclosure_shown_for=email,picture

Po otrzymaniu żądania serwer powinien:

  1. Odpowiedz na żądanie za pomocą CORS (Cross-Origin Resource Sharing).
  2. Sprawdź, czy żądanie zawiera nagłówek HTTP Sec-Fetch-Dest: webidentity.
  3. Porównaj nagłówek Origin ze źródłem RP określonym przez client_id. Odrzuć, jeśli nie pasują.
  4. Porównaj wartość account_id z identyfikatorem konta, na które użytkownik jest już zalogowany. Odrzuć, jeśli nie pasują.
  5. Odpowiedz za pomocą tokena. Jeśli żądanie zostanie odrzucone, odpowiedz błędem.

Dostawca tożsamości może zdecydować, w jaki sposób wyda token. Zwykle jest on podpisany informacjami takimi jak identyfikator konta, identyfikator klienta, pochodzenie wystawcy i wartość nonce, dzięki czemu RP może zweryfikować, czy token jest autentyczny.

Przeglądarka oczekuje odpowiedzi w formacie JSON, która zawiera tę właściwość:

Właściwość Opis
token Token to ciąg tekstowy zawierający informacje o uwierzytelnianiu.
continue_on Adres URL przekierowania, który umożliwia wieloetapowy proces logowania.

Zwrócony token jest przekazywany do strony zależnej przez przeglądarkę, aby strona zależna mogła zweryfikować uwierzytelnianie.

  {
    // IdP can respond with a token to authenticate the user
    "token": "***********"
  }

Kontynuuj w funkcji

Dostawca tożsamości może podać adres URL przekierowania w odpowiedzi punktu końcowego potwierdzenia tożsamości, aby umożliwić wieloetapowy proces logowania. Jest to przydatne, gdy dostawca tożsamości musi poprosić o dodatkowe informacje lub uprawnienia, na przykład:

  • Uprawnienia dostępu do zasobów po stronie serwera użytkownika.
  • Sprawdzenie, czy informacje kontaktowe są aktualne.
  • Kontrola rodzicielska.

Punkt końcowy potwierdzenia tożsamości może zwracać właściwość continue_on, która zawiera bezwzględną lub względną ścieżkę do punktu końcowego potwierdzenia tożsamości.

  {
    // 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"
  }

Jeśli odpowiedź zawiera parametr continue_on, otworzy się nowe okno wyskakujące, w którym użytkownik zostanie przekierowany do określonej ścieżki. Po interakcji użytkownika ze stroną continue_on dostawca tożsamości powinien wywołać funkcję IdentityProvider.resolve(), przekazując token jako argument, aby można było rozstrzygnąć obietnicę z pierwotnego wywołania navigator.credentials.get():

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

Przeglądarka automatycznie zamknie wyskakujące okienko i zwróci token do wywołującego interfejs API. Jednorazowe wywołanie IdentityProvider.resolve() to jedyny sposób komunikacji między oknem nadrzędnym (RP) a wyskakującym okienkiem (IdP).
Jeśli użytkownik odrzuci prośbę, dostawca tożsamości może zamknąć okno, wywołując funkcję IdentityProvider.close().

  IdentityProvider.close();

Interfejs Continuation API wymaga do działania wyraźnej interakcji użytkownika (kliknięć). Interfejs Continuation API działa w różnych trybach mediacji w ten sposób:

  • W passive trybie:
    • mediation: 'optional' (domyślnie): interfejs Continuation API będzie działać tylko w przypadku działania użytkownika, np. kliknięcia przycisku na stronie lub w interfejsie FedCM. Gdy automatyczne ponowne uwierzytelnianie zostanie wywołane bez gestu użytkownika, nie zostanie otwarte żadne wyskakujące okienko, a obietnica zostanie odrzucona.
    • mediation: 'required': zawsze prosi użytkownika o interakcję, więc interfejs Continuation API zawsze działa.
  • W trybie aktywnym:
    • Aktywacja użytkownika jest zawsze wymagana. Interfejs Continuation API jest zawsze zgodny.

Jeśli z jakiegoś powodu użytkownik zmienił konto w wyskakującym okienku (np. dostawca tożsamości oferuje funkcję „użyj innego konta” lub w przypadku przekazywania dostępu), wywołanie resolve przyjmuje opcjonalny drugi argument, który umożliwia wykonanie działania podobnego do tego:

  IdentityProvider.resolve(token, {accountId: '1234');

Zwracanie komunikatu o błędzie

id_assertion_endpoint może też zwrócić odpowiedź „error”, która ma 2 pola opcjonalne:

  • code: dostawca tożsamości może wybrać jeden ze znanych błędów z listy błędów określonych w OAuth 2.0 (invalid_request, unauthorized_client, access_denied, server_errortemporarily_unavailable) lub użyć dowolnego ciągu znaków. W tym drugim przypadku Chrome renderuje interfejs błędu z ogólnym komunikatem o błędzie i przekazuje kod do dostawcy tożsamości.
  • url: identyfikuje stronę internetową z informacjami o błędzie, które są czytelne dla użytkowników. To pole jest przydatne dla użytkowników, ponieważ przeglądarki nie mogą wyświetlać rozbudowanych komunikatów o błędach w wbudowanym interfejsie. Na przykład: linki do kolejnych kroków lub dane kontaktowe obsługi klienta. Jeśli użytkownik chce dowiedzieć się więcej o szczegółach błędu i sposobach jego naprawienia, może odwiedzić podaną stronę w interfejsie przeglądarki, aby uzyskać więcej informacji. Adres URL musi należeć do tej samej witryny co dostawca tożsamości configURL.
  // id_assertion_endpoint response
  {
    "error" : {
      "code": "access_denied",
      "url" : "https://idp.example/error?type=access_denied"
    }
  }

Etykiety własne konta

Dzięki niestandardowym etykietom kont dostawca tożsamości może dodawać do kont użytkowników etykiety, a dostawca usługi może pobierać tylko konta z określonymi etykietami, podając configURL dla danej etykiety. Może to być przydatne, gdy dostawca tożsamości musi odfiltrować konta według określonych kryteriów, np. aby wyświetlać tylko konta przypisane do ról, takie jak "developer" lub "hr".

Podobne filtrowanie jest możliwe przy użyciu funkcji Wskazówka dotycząca domeny i Wskazówka dotycząca logowania, które można określić w wywołaniu navigator.credentials.get(). Etykiety kont niestandardowych mogą jednak filtrować użytkowników, określając plik konfiguracyjny, co jest szczególnie przydatne, gdy używanych jest wiele adresów URL konfiguracji. Niestandardowe etykiety konta różnią się też tym, że są dostarczane z serwera dostawcy tożsamości, a nie z serwera dostawcy usługi, jak wskazówki dotyczące logowania lub domeny.

Rozważmy dostawcę tożsamości, który chce rozróżniać konta "developer""hr". Aby to osiągnąć, dostawca tożsamości musi obsługiwać 2 adresy URL konfiguracji odpowiednio dla "developer""hr":

  • Plik konfiguracji dewelopera https://idp.example/developer/fedcm.json ma etykietę "developer", a plik konfiguracji przedsiębiorstwa https://idp.example/hr/fedcm.json ma etykietę "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",
    "account_label": "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",
    "account_label": "hr"
  }
  • W takiej konfiguracji plik well-known powinien zawierać accounts_endpointlogin_url, aby umożliwić używanie wielu adresów URL konfiguracji:
  {
    "provider_urls": [ "https://idp.example/fedcm.json" ],
    "accounts_endpoint": "https://idp.example/accounts",
    "login_url": "https://idp.example/login"
  }
  • Wspólny punkt końcowy kont dostawcy tożsamości (w tym przykładzie https://idp.example/accounts) zwraca listę kont, która zawiera właściwość label_hints z przypisanymi etykietami w tablicy dla każdego konta:
  {
  "accounts": [{
    "id": "123",
    "given_name": "John",
    "name": "John Doe",
    "email": "john_doe@idp.example",
    "picture": "https://idp.example/profile/123",
    "label_hints": ["developer"]
    }], [{
    "id": "4567",
    "given_name": "Jane",
    "name": "Jane Doe",
    "email": "jane_doe@idp.example",
    "picture": "https://idp.example/profile/4567",
    "label_hints": ["hr"]
    }]
  }

Gdy dostawca tożsamości chce zezwolić użytkownikom na logowanie się, może określić adres URL konfiguracji https://idp.example/hr/fedcm.json w wywołaniu navigator.credentials.get():"hr"

  let { token } = await navigator.credentials.get({
    identity: {
      providers: [{
        clientId: '1234',
        nonce: '234234',
        configURL: 'https://idp.example/hr/fedcm.json',
      },
    }
  });

W rezultacie użytkownik może zalogować się tylko za pomocą identyfikatora konta 4567. Identyfikator konta 123 jest ukrywany przez przeglądarkę, aby użytkownik nie otrzymał konta, które nie jest obsługiwane przez dostawcę tożsamości w tej witrynie.

Dodatkowe uwagi:

  • Etykiety to ciągi znaków. Jeśli tablica label_hints lub pole account_label używa wartości, która nie jest ciągiem znaków, wartość jest ignorowana.
  • Jeśli w configURL nie określono żadnych etykiet, w selektorze kont FedCM będą wyświetlane wszystkie konta.
  • Jeśli dla konta nie określono żadnych etykiet, będzie ono wyświetlane w selektorze kont tylko wtedy, gdy configURL również nie określa etykiety.
  • Jeśli w trybie pasywnym (podobnie jak w przypadku funkcji Domain Hint) nie ma konta pasującego do żądanej etykiety, w oknie FedCM wyświetli się prośba o zalogowanie, która umożliwi użytkownikowi zalogowanie się na konto dostawcy tożsamości. W trybie aktywnym okno logowania otwiera się bezpośrednio.

Odłączanie punktu końcowego

Po wywołaniu IdentityCredential.disconnect() przeglądarka wysyła żądanie z innej domenyPOST z plikami cookie z SameSite=None i typem treści application/x-www-form-urlencoded do tego punktu końcowego rozłączania z tymi informacjami:

Właściwość Opis
account_hint Wskazówka dotycząca konta dostawcy tożsamości.
client_id Identyfikator klienta 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

Po otrzymaniu żądania serwer powinien:

  1. Odpowiedz na żądanie za pomocą CORS (Cross-Origin Resource Sharing).
  2. Sprawdź, czy żądanie zawiera nagłówek HTTP Sec-Fetch-Dest: webidentity.
  3. Porównaj nagłówek Origin ze źródłem RP określonym przez client_id. Odrzuć, jeśli nie pasują.
  4. Dopasuj account_hint do identyfikatorów kont, z których obecnie korzystasz.
  5. Odłącz konto użytkownika od dostawcy tożsamości.
  6. Odpowiedz przeglądarce, przesyłając informacje o zidentyfikowanym koncie użytkownika w formacie JSON.

Przykładowy ładunek JSON odpowiedzi wygląda tak:

  {
    "account_id": "account456"
  }

Jeśli dostawca tożsamości chce, aby przeglądarka odłączyła wszystkie konta powiązane z usługą, przekaż ciąg znaków, który nie pasuje do żadnego identyfikatora konta, np. "*".

Punkt końcowy metadanych klienta

Punkt końcowy metadanych klienta dostawcy tożsamości zwraca metadane strony ufającej, takie jak polityka prywatności, warunki korzystania z usługi i ikony logo. Usługi RP powinny z wyprzedzeniem przekazać dostawcy tożsamości linki do swojej polityki prywatności i warunków korzystania z usługi. Te linki są wyświetlane w oknie logowania, gdy użytkownik nie zarejestrował się jeszcze w RP za pomocą dostawcy tożsamości.

Przeglądarka wysyła żądanie GET przy użyciu client_id navigator.credentials.get bez plików cookie. Na przykład:

  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

Po otrzymaniu żądania serwer powinien:

  1. Określ RP dla client_id.
  2. Odpowiedz metadanymi klienta.

Właściwości punktu końcowego metadanych klienta:

Właściwość Opis
privacy_policy_url (opcjonalnie) Adres URL polityki prywatności RP.
terms_of_service_url (opcjonalnie) Adres URL warunków korzystania z usługi RP.
icons (opcjonalnie) Tablica obiektów, np. [{ "url": "https://rp.example/rp-icon.ico", "size": 40}]

Przeglądarka oczekuje odpowiedzi JSON z punktu końcowego:

  {
    "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
      }]
  }

Zwrócone metadane klienta są wykorzystywane przez przeglądarkę i nie są dostępne dla dostawcy tożsamości.

URL logowania

Ten punkt końcowy służy do logowania użytkownika w systemie dostawcy tożsamości.

Za pomocą interfejsu Login Status API dostawca tożsamości musi informować przeglądarkę o stanie logowania użytkownika. Stan może jednak być niespójny, np. gdy sesja wygaśnie. W takim przypadku przeglądarka może dynamicznie zezwolić użytkownikowi na zalogowanie się u dostawcy tożsamości na stronie logowania, której adres URL jest określony w pliku konfiguracji dostawcy tożsamości za pomocą parametru login_url.

W oknie dialogowym FedCM wyświetla się komunikat z propozycją zalogowania się, jak pokazano na ilustracji poniżej.

Okienko FedCM z prośbą o zalogowanie się u dostawcy tożsamości.
Okno FedCM z propozycją zalogowania się u dostawcy tożsamości.

Gdy użytkownik kliknie przycisk Dalej, przeglądarka otworzy wyskakujące okienko ze stroną logowania dostawcy tożsamości.

Przykład okna FedCM.
Przykład okna dialogowego wyświetlanego po kliknięciu przycisku logowania u dostawcy tożsamości.

Okno dialogowe to zwykłe okno przeglądarki, które ma własne pliki cookie. To, co dzieje się w oknie dialogowym, zależy od dostawcy tożsamości. Nie są dostępne żadne uchwyty okien, które umożliwiałyby wysłanie żądania komunikacji między źródłami do strony RP. Po zalogowaniu się użytkownika dostawca tożsamości powinien:

  • Wyślij nagłówek Set-Login: logged-in lub wywołaj interfejs API navigator.login.setStatus("logged-in"), aby poinformować przeglądarkę, że użytkownik zalogował się.
  • Wywołaj IdentityProvider.close(), aby zamknąć okno.
Użytkownik loguje się w RP po zalogowaniu się w IdP za pomocą FedCM.

Informowanie przeglądarki o stanie logowania użytkownika

Interfejs Login Status API to mechanizm, dzięki któremu witryna, zwłaszcza dostawca tożsamości, informuje przeglądarkę o stanie logowania użytkownika u dostawcy tożsamości. Dzięki temu interfejsowi API przeglądarka może ograniczyć liczbę niepotrzebnych żądań do dostawcy tożsamości i zmniejszyć ryzyko potencjalnych ataków czasowych.

Dostawcy tożsamości mogą sygnalizować przeglądarce stan logowania użytkownika, wysyłając nagłówek HTTP lub wywołując interfejs JavaScript API, gdy użytkownik jest zalogowany u dostawcy tożsamości lub gdy jest wylogowany ze wszystkich kont u dostawcy tożsamości. W przypadku każdego dostawcy tożsamości (identyfikowanego przez adres URL konfiguracji) przeglądarka przechowuje trójstanową zmienną reprezentującą stan logowania, która może przyjmować te wartości:

  • logged-in
  • logged-out
  • unknown (domyślnie)
Stan logowania Opis
logged-in Gdy stan logowania użytkownika jest ustawiony na logged-in, RP wywołujący FedCM wysyła żądania do punktu końcowego kont dostawcy tożsamości i wyświetla dostępne konta w oknie FedCM.
logged-out Gdy stan logowania użytkownika to logged-out, wywołanie FedCM kończy się niepowodzeniem bez wysyłania żądania do punktu końcowego kont dostawcy tożsamości.
unknown (domyślnie) Stan unknown jest ustawiany, zanim dostawca tożsamości wyśle sygnał za pomocą interfejsu Login Status API. Gdy stan to unknown, przeglądarka wysyła żądanie do punktu końcowego kont dostawcy tożsamości i aktualizuje stan na podstawie odpowiedzi z punktu końcowego kont.

Aby zasygnalizować, że użytkownik jest zalogowany, wyślij Set-Login: logged-in nagłówek HTTP w żądaniu nawigacji najwyższego poziomu lub w żądaniu zasobu podrzędnego w tej samej witrynie w domenie dostawcy tożsamości:

  Set-Login: logged-in

Możesz też wywołać metodę JavaScriptu navigator.login.setStatus('logged-in') ze źródła dostawcy tożsamości w nawigacji najwyższego poziomu:

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

Stan logowania użytkownika zostanie ustawiony jako logged-in.

Aby zasygnalizować, że użytkownik jest wylogowany ze wszystkich kont, wyślij nagłówek HTTP Set-Login: logged-out w żądaniu nawigacji najwyższego poziomu lub w żądaniu zasobu podrzędnego w tej samej witrynie w domenie dostawcy tożsamości:

  Set-Login: logged-out

Możesz też wywołać interfejs JavaScript API navigator.login.setStatus('logged-out')ze źródła dostawcy tożsamości w nawigacji najwyższego poziomu:

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

Stan logowania użytkownika zostanie ustawiony jako logged-out.

Stan unknown jest ustawiany przed wysłaniem sygnału przez dostawcę tożsamości za pomocą interfejsu Login Status API. Przeglądarka wysyła żądanie do punktu końcowego kont dostawcy tożsamości i aktualizuje stan na podstawie odpowiedzi z tego punktu:

  • Jeśli punkt końcowy zwróci listę aktywnych kont, zaktualizuj stan na logged-in i otwórz okno FedCM, aby wyświetlić te konta.
  • Jeśli punkt końcowy nie zwróci żadnych kont, zaktualizuj stan na logged-out i zakończ niepowodzeniem wywołanie FedCM.

Umożliwianie użytkownikowi logowania się za pomocą dynamicznego procesu logowania

Mimo że dostawca tożsamości stale informuje przeglądarkę o stanie logowania użytkownika, może dojść do rozbieżności, np. gdy sesja wygaśnie. Gdy stan logowania to logged-in, przeglądarka próbuje wysłać do punktu końcowego kont żądanie z danymi logowania, ale serwer nie zwraca żadnych kont, ponieważ sesja jest już niedostępna. W takim przypadku przeglądarka może dynamicznie zezwolić użytkownikowi na zalogowanie się w usłudze dostawcy tożsamości w wyskakującym okienku.

Dalsze kroki

Wdrożyć FedCM w przypadku swoich RP i rozpowszechnić pakiet SDK JavaScript. Utrzymywanie aktualności RP przez wyeliminowanie konieczności samodzielnego wdrażania.
Dowiedz się, jak skonfigurować środowisko i debugować implementację.