La implementación de FedCM incluye varios pasos fundamentales para el Proveedor de identidad (IdP) y el Grupo de confianza (RP). Consulta la documentación para aprender a implementar FedCM en el lado del RP.
Los IdPs deben completar los siguientes pasos para implementar FedCM:
- Crea un archivo conocido.
- Crea un archivo de configuración.
- Crea los siguientes extremos:
- Informa al navegador sobre el estado de acceso del usuario.
Crea un archivo conocido
Para evitar que los agentes de seguimiento abusen de la API, se debe entregar un archivo conocido desde /.well-known/web-identity
del eTLD+1 del IdP.
El archivo conocido puede incluir las siguientes propiedades:
Propiedad | Obligatorio | Descripción |
---|---|---|
provider_urls
|
obligatorio | Es un array de rutas de acceso de archivos de configuración del IdP. Se ignora (pero aún es obligatorio) si se especifican accounts_endpoint y login_url . |
accounts_endpoint
|
recomendado, requiere login_url |
Es la URL del extremo de cuentas. Esto permite admitir varias configuraciones, siempre que cada archivo de configuración use la misma URL de login_url y accounts_endpoint .Nota: El parámetro es compatible a partir de Chrome 132. |
login_url
|
recomendado, requiere accounts_endpoint |
La URL de la página de acceso para que el usuario acceda al IdP. Esto permite admitir varias configuraciones, siempre que cada archivo de configuración use los mismos login_url y accounts_endpoint .Nota: El parámetro es compatible a partir de Chrome 132 y versiones posteriores. |
Por ejemplo, si los extremos del IdP se entregan en https://accounts.idp.example/
, deben entregar un archivo well-known en https://idp.example/.well-known/web-identity
, así como un archivo de configuración del IdP. Este es un ejemplo de contenido de archivo conocido:
{
"provider_urls": ["https://accounts.idp.example/config.json"]
}
Los proveedores de identidad pueden admitir varios archivos de configuración para un proveedor de identidad. Para ello, especifica accounts_endpoint
y login_url
en el archivo conocido.
Esta función puede ser útil en los siguientes casos:
- Un IdP debe admitir varias configuraciones de prueba y producción diferentes.
- Un IdP debe admitir diferentes configuraciones por región (por ejemplo,
eu-idp.example
yus-idp.example
).
Para admitir varias configuraciones (por ejemplo, para diferenciar entre el entorno de prueba y el de producción), la AC debe especificar accounts_endpoint
y 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"
}
Crea un archivo de configuración y extremos del IdP
El archivo de configuración del IdP proporciona una lista de los extremos necesarios para el navegador. Las IdP deben alojar uno o varios archivos de configuración, y los extremos y las URLs necesarios. Todas las respuestas JSON se deben entregar con el tipo de contenido application/json
.
La URL del archivo de configuración se determina según los valores proporcionados a la llamada navigator.credentials.get()
que se ejecuta en un RP.
const credential = await navigator.credentials.get({
identity: {
context: 'signup',
providers: [{
configURL: 'https://accounts.idp.example/config.json',
clientId: '********',
nonce: '******'
}]
}
});
const { token } = credential;
El RP pasará la URL del archivo de configuración a la llamada a la API de FedCM para permitir que el usuario acceda:
// 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;
El navegador recuperará el archivo de configuración con una solicitud GET
sin el encabezado Origin
ni el encabezado Referer
. La solicitud no tiene cookies y no sigue redireccionamientos. Esto evita que la AC sepa quién realizó la solicitud y qué RP intenta conectarse. Por ejemplo:
GET /config.json HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Sec-Fetch-Dest: webidentity
El IdP debe implementar un extremo de configuración que responda con un JSON. El JSON incluye las siguientes propiedades:
Propiedad | Descripción |
---|---|
accounts_endpoint (obligatorio) |
Es la URL del extremo de cuentas. |
accounts.include (opcional)
|
Es una cadena de etiqueta de cuenta personalizada que determina qué cuentas se deben mostrar cuando se usa este archivo de configuración, por ejemplo: "accounts": {"include": "developer"} .
Un IdP puede implementar el etiquetado de cuentas personalizado de la siguiente manera:
Por ejemplo, un IdP implementa el archivo de configuración "https://idp.example/developer-config.json" con "accounts": {"include": "developer"} especificado. El IdP también marca algunas cuentas con la etiqueta "developer" con el parámetro labels en el extremo de cuentas. Cuando un RP llama a navigator.credentials.get() con el archivo de configuración "https://idp.example/developer-config.json" especificado, solo se muestran las cuentas con la etiqueta "developer" .Nota: Las etiquetas de cuenta personalizadas son compatibles a partir de Chrome 132. |
client_metadata_endpoint (opcional) |
Es la URL del extremo de metadatos del cliente. |
id_assertion_endpoint (obligatorio) |
Es la URL del extremo de aserción de ID. |
disconnect (opcional) |
Es la URL del extremo de desconexión. |
login_url (obligatorio) |
La URL de la página de acceso para que el usuario acceda al IdP. |
branding (opcional) |
Es un objeto que contiene varias opciones de desarrollo de la marca. |
branding.background_color (opcional) |
Es una opción de desarrollo de la marca que establece el color de fondo del botón "Continuar como…". Usa la sintaxis CSS relevante, es decir, hex-color , hsl() , rgb() o named-color . |
branding.color (opcional) |
Es una opción de desarrollo de la marca que establece el color del texto del botón "Continuar como…". Usa la sintaxis CSS relevante, es decir, hex-color , hsl() , rgb() o named-color . |
branding.icons (opcional) |
Array de objetos de íconos. Estos íconos se muestran en el diálogo de acceso. El objeto de ícono tiene dos parámetros:
|
modes |
Objeto que contiene especificaciones sobre cómo se mostrará la IU de FedCM en diferentes modos:
|
modes.active
|
Objeto que contiene propiedades que permiten personalizar el comportamiento de FedCM en un modo específico. Tanto modes.active como modes.passive pueden contener el siguiente parámetro:
Nota: La función Usar otra cuenta y el modo activo son compatibles a partir de Chrome 132. |
modes.passive
|
Este es un ejemplo de cuerpo de respuesta del 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
}]
}
}
Una vez que el navegador recupera el archivo de configuración, envía solicitudes posteriores a los extremos del IdP:
![Extremos del IdP](https://developers.google.cn/static/privacy-sandbox/assets/images/fedcm/fedcm-flow-diagram.png?hl=es-419)
Usar otra cuenta
Los usuarios pueden cambiar a una cuenta que sea diferente de la que usan actualmente si la AC admite varias cuentas o reemplaza la cuenta existente.
Para permitir que el usuario elija otras cuentas, la AC debe especificar esta función en el archivo de configuración:
{
"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
}
}
Extremo de cuentas
El extremo de cuentas del IdP muestra una lista de las cuentas a las que el usuario accedió en el IdP. Si la AC admite varias cuentas, este extremo mostrará todas las cuentas a las que se accedió.
El navegador envía una solicitud GET
con cookies con SameSite=None
, pero sin un parámetro client_id
, el encabezado Origin
ni el encabezado Referer
. Esto evita de manera eficaz que el IdP sepa a qué RP intenta acceder el usuario. Por ejemplo:
GET /accounts.example HTTP/1.1
Host: accounts.idp.example
Accept: application/json
Cookie: 0x23223
Sec-Fetch-Dest: webidentity
Cuando recibe la solicitud, el servidor debe hacer lo siguiente:
- Verifica que la solicitud contenga un encabezado HTTP
Sec-Fetch-Dest: webidentity
. - Haz coincidir las cookies de sesión con los IDs de las cuentas a las que ya se accedió.
- Responde con la lista de cuentas.
El navegador espera una respuesta JSON que incluya una propiedad accounts
con un array de información de la cuenta con las siguientes propiedades:
Propiedad | Descripción |
---|---|
id (obligatorio) |
Es el ID único del usuario. |
name (obligatorio) |
Es el nombre y apellido del usuario. |
email (obligatorio) |
Es la dirección de correo electrónico del usuario. |
given_name (opcional) |
Es el nombre de pila del usuario. |
picture (opcional) |
Es la URL de la imagen del avatar del usuario. |
approved_clients (opcional) |
Es un array de IDs de cliente de RP con los que se registró el usuario. |
login_hints (opcional) |
Es un array de todos los tipos de filtros posibles que admite el IdP para especificar una cuenta. El RP puede invocar navigator.credentials.get() con la propiedad loginHint para mostrar de forma selectiva la cuenta especificada. |
domain_hints (opcional) |
Es un array de todos los dominios con los que está asociada la cuenta. El RP puede llamar a navigator.credentials.get() con una propiedad domainHint para filtrar las cuentas. |
labels (opcional)
|
Es un array de cadenas de etiquetas de cuenta personalizadas con las que está asociada una cuenta. Un IdP puede implementar el etiquetado de cuentas personalizado de la siguiente manera:
Por ejemplo, un IdP implementa el archivo de configuración https://idp.example/developer-config.json con "accounts": {"include": "developer"} especificado. El IdP también marca algunas cuentas con la etiqueta "developer" con el parámetro labels en el extremo de cuentas. Cuando un RP llama a navigator.credentials.get() con el archivo de configuración https://idp.example/developer-config.json especificado, solo se muestran las cuentas con la etiqueta "developer" .Las etiquetas de cuenta personalizadas son diferentes de las sugerencias de acceso y de dominio de manera tal que el servidor de IdP las mantiene por completo, y el RP solo especifica el archivo de configuración que se usará. Nota: Las etiquetas de cuenta personalizadas son compatibles a partir de Chrome 132. |
Cuerpo de la respuesta de ejemplo:
{
"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"]
}]
}
Si el usuario no accedió, responde con HTTP 401
(sin autorización).
El navegador consume la lista de cuentas que se muestra y no estará disponible para el RP.
Extremo de aserción de ID
El extremo de aserción de ID del IdP muestra una aserción para el usuario que accedió.
Cuando el usuario accede a un sitio web de RP con una llamada navigator.credentials.get()
, el navegador envía una solicitud POST
con cookies con SameSite=None
y un tipo de contenido de application/x-www-form-urlencoded
a este extremo con la siguiente información:
Propiedad | Descripción |
---|---|
client_id (obligatorio) |
Es el identificador de cliente del RP. |
account_id (obligatorio) |
El ID único del usuario que accede |
disclosure_text_shown |
Genera una cadena de "true" o "false" (en lugar de un valor booleano). El resultado es "false" en estos casos:
|
is_auto_selected |
Si se realiza la reautorización automática en la RP, is_auto_selected indica "true" . De lo contrario, "false" . Esto es útil para admitir más funciones relacionadas con la seguridad. Por ejemplo, algunos usuarios pueden preferir un nivel de seguridad más alto que requiera mediación explícita del usuario en la autenticación. Si una AC recibe una solicitud de token sin esa mediación, podría controlar la solicitud de manera diferente. Por ejemplo, muestra un código de error para que el RP pueda volver a llamar a la API de FedCM con mediation: required . |
fields (opcional)
|
Es un array de cadenas que especifica la información del usuario ("name", "email", "picture") que el RP necesita que la AC comparta con él. El navegador enviará fields , disclosure_text_shown y disclosure_shown_for con una lista de los campos especificados en la solicitud POST, como en el siguiente ejemplo.Nota: El parámetro Fields es compatible a partir de Chrome 132. |
params (opcional)
|
Cualquier objeto JSON válido que permita especificar parámetros clave-valor personalizados adicionales, por ejemplo:
params se serializará a JSON y, luego, se codificará en porcentaje.Nota: La API de Parameters es compatible con Chrome 132 y versiones posteriores. |
Ejemplo de encabezado 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
Cuando recibe la solicitud, el servidor debe hacer lo siguiente:
- Responde la solicitud con CORS (uso compartido de recursos entre dominios).
- Verifica que la solicitud contenga un encabezado HTTP
Sec-Fetch-Dest: webidentity
. - Haz coincidir el encabezado
Origin
con el origen de RP determinado porclient_id
. Rechaza la solicitud si no coincide. - Haz coincidir
account_id
con el ID de la cuenta a la que ya se accedió. Rechaza la solicitud si no coinciden. - Responde con un token. Si se rechaza la solicitud, responde con una respuesta de error.
El IdP puede decidir cómo emitir el token. En general, está firmado con información como el ID de la cuenta, el ID del cliente, el origen del emisor y el nonce, de modo que la RP pueda verificar que el token es original.
El navegador espera una respuesta JSON que incluya la siguiente propiedad:
Propiedad | Descripción |
---|---|
token |
Un token es una cadena que contiene declaraciones sobre la autenticación. |
continue_on |
Es la URL de redireccionamiento que habilita un flujo de acceso de varios pasos. |
El navegador pasa el token que se muestra a la RP para que esta pueda validar la autenticación.
{
// IdP can respond with a token to authenticate the user
"token": "***********"
}
Continuar en la función
El IdP puede proporcionar una URL de redireccionamiento en la respuesta del extremo de la aserción de ID para habilitar un flujo de acceso de varios pasos. Esto es útil cuando la AC necesita solicitar información o permisos adicionales, por ejemplo:
- Permiso para acceder a los recursos del servidor del usuario
- Verificación de que la información de contacto esté actualizada
- Controles parentales.
El extremo de la aserción de ID puede mostrar una propiedad continue_on
que incluye una ruta de acceso absoluta o relativa al extremo de la aserción de ID.
{
// 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"
}
Si la respuesta contiene el parámetro continue_on
, se abre una nueva ventana emergente y se dirige al usuario a la ruta de acceso especificada. Después de la interacción del usuario con la página continue_on
, el IdP debe llamar a IdentityProvider.resolve()
con el token pasado como argumento para que se pueda resolver la promesa de la llamada navigator.credentials.get()
original:
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);
});
Luego, el navegador cerrará automáticamente la ventana emergente y devolverá el token al llamador de la API. Una llamada IdentityProvider.resolve()
única es la única forma en que la ventana superior (RP) y la ventana emergente (IdP) pueden comunicarse.
Si el usuario rechaza la solicitud, el IdP puede llamar a IdentityProvider.close()
para cerrar la ventana.
IdentityProvider.close();
La API de Continuation requiere interacción explícita del usuario (clics) para funcionar. A continuación, se muestra cómo funciona la API de Continuation con diferentes modos de mediación:
- En el modo pasivo:
mediation: 'optional'
(predeterminada): La API de Continuation solo funcionará con un gesto del usuario, como hacer clic en un botón de la página o en la IU de FedCM. Cuando se activa la reautorización automática sin un gesto del usuario, no se abre una ventana emergente y se rechaza la promesa.mediation: 'required'
: Siempre le pide al usuario que interactúe, por lo que la API de Continuation siempre funciona.
- En el modo activo:
- La activación del usuario siempre es obligatoria. La API de Continuation es compatible.
Si, por algún motivo, el usuario cambió su cuenta en la ventana emergente (por ejemplo, el IdP ofrece una función "Usar otra cuenta" o en casos de delegación), la llamada de resolución toma un segundo argumento opcional que permite algo como lo siguiente:
IdentityProvider.resolve(token, {accountId: '1234');
Cómo mostrar una respuesta de error
id_assertion_endpoint
también puede mostrar una respuesta de “error”, que tiene dos campos opcionales:
code
: El IdP puede elegir uno de los errores conocidos de la lista de errores especificada de OAuth 2.0 (invalid_request
,unauthorized_client
,access_denied
,server_error
ytemporarily_unavailable
) o usar cualquier cadena arbitraria. Si es así, Chrome renderiza la IU de error con un mensaje de error genérico y pasa el código a la RP.url
: Identifica una página web legible por humanos con información sobre el error para proporcionar información adicional a los usuarios. Este campo es útil para los usuarios porque los navegadores no pueden proporcionar mensajes de error enriquecidos en una IU integrada. Por ejemplo, vínculos para los próximos pasos o información de contacto del servicio de atención al cliente. Si un usuario quiere obtener más información sobre los detalles del error y cómo corregirlo, puede visitar la página proporcionada desde la IU del navegador para obtener más detalles. La URL debe ser del mismo sitio que elconfigURL
de la IdP.
// id_assertion_endpoint response
{
"error" : {
"code": "access_denied",
"url" : "https://idp.example/error?type=access_denied"
}
}
Etiquetas de cuenta personalizadas
Con las etiquetas de cuenta personalizadas, el IdP puede anotar cuentas de usuario con etiquetas, y el RP puede elegir recuperar solo cuentas con etiquetas específicas especificando el configURL
para esa etiqueta específica. Esto puede ser útil cuando un RP necesita filtrar cuentas según criterios específicos, por ejemplo, para mostrar solo cuentas específicas de roles, como "developer"
o "hr"
.
Es posible realizar un filtrado similar con las funciones Domain Hint y Login Hint. Para ello, especifícalas en la llamada a navigator.credentials.get()
. Sin embargo, las etiquetas de cuenta personalizadas pueden filtrar usuarios especificando el archivo de configuración, lo que es especialmente útil cuando se usan multiples configURLs. Las etiquetas de cuenta personalizadas también son diferentes en que se proporcionan desde el servidor del IdP, en lugar de desde el RP, como las sugerencias de acceso o dominio.
Considera un IdP que desea diferenciar entre cuentas "developer"
y "hr"
. Para lograrlo, el IdP debe admitir dos configURLs para "developer"
y "hr"
, respectivamente:
- El archivo de configuración para desarrolladores
https://idp.example/developer/fedcm.json
tiene una etiqueta"developer"
, y el archivo de configuración empresarialhttps://idp.example/hr/fedcm.json
tiene una etiqueta"hr"
de la siguiente manera:
// 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"
}
}
- Con esa configuración, el archivo conocido debe incluir
accounts_endpoint
ylogin_url
para permitir múltiples configURLs:
{
"provider_urls": [ "https://idp.example/fedcm.json" ],
"accounts_endpoint": "https://idp.example/accounts",
"login_url": "https://idp.example/login"
}
- El extremo de cuentas común del IdP (en este ejemplo,
https://idp.example/accounts
) muestra una lista de cuentas que incluye una propiedadlabels
con etiquetas asignadas en un array para cada cuenta:
{
"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"]
}]
}
Cuando un RP desea permitir que los usuarios de "hr"
accedan, puede especificar el https://idp.example/hr/fedcm.json
de configURL en la llamada a navigator.credentials.get()
:
let { token } = await navigator.credentials.get({
identity: {
providers: [{
clientId: '1234',
nonce: '234234',
configURL: 'https://idp.example/hr/fedcm.json',
},
}
});
Como resultado, solo el ID de la cuenta de 4567
está disponible para que el usuario acceda.
El navegador oculta de forma silenciosa el ID de la cuenta de 123
para que no se le proporcione al usuario una cuenta que no sea compatible con el IdP en este sitio.
- Las etiquetas son cadenas. Si el array
labels
o el campoinclude
contiene algo que no es una cadena, se ignora. - Si no se especifican etiquetas en
configURL
, todas las cuentas se mostrarán en el selector de cuentas de FedCM. - Si no se especifican etiquetas para una cuenta, solo se mostrará en el selector de cuentas si
configURL
tampoco especifica una etiqueta. - Si no hay ninguna cuenta que coincida con la etiqueta solicitada en el modo pasivo (similar a la función de sugerencia de dominio), el diálogo de FedCM muestra un mensaje de acceso, que le permite al usuario acceder a una cuenta de IdP. En el modo activo, la ventana emergente de acceso se abre directamente.
Desconecta el extremo
Cuando se invoca IdentityCredential.disconnect()
, el navegador envía una solicitud POST
de origen cruzado con cookies con SameSite=None
y un tipo de contenido de application/x-www-form-urlencoded
a este extremo de desconexión con la siguiente información:
Propiedad | Descripción |
---|---|
account_hint |
Una sugerencia para la cuenta de IdP. |
client_id |
Es el identificador de cliente del 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
Cuando recibe la solicitud, el servidor debe hacer lo siguiente:
- Responde la solicitud con CORS (uso compartido de recursos entre dominios).
- Verifica que la solicitud contenga un encabezado HTTP
Sec-Fetch-Dest: webidentity
. - Haz coincidir el encabezado
Origin
con el origen de RP determinado porclient_id
. Rechaza la solicitud si no coincide. - Haz coincidir
account_hint
con los IDs de las cuentas a las que ya se accedió. - Desconecta la cuenta de usuario del RP.
- Responde al navegador con la información de la cuenta de usuario identificada en formato JSON.
Una carga útil de JSON de respuesta de ejemplo se ve de la siguiente manera:
{
"account_id": "account456"
}
En cambio, si el IdP desea que el navegador desconecte todas las cuentas asociadas con el RP, pasa una cadena que no coincida con ningún ID de cuenta, por ejemplo, "*"
.
Extremo de metadatos del cliente
El extremo de metadatos del cliente de la AC muestra los metadatos de la parte de confianza, como la política de privacidad, las condiciones del servicio y los íconos de logotipos de la RP. Los RP deben proporcionar vínculos a su política de privacidad y a sus Condiciones del Servicio a la AC con anticipación. Estos vínculos se muestran en el diálogo de acceso cuando el usuario aún no se registró en la RP con la AC.
El navegador envía una solicitud GET
con client_id
navigator.credentials.get
sin cookies. Por ejemplo:
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
Cuando recibe la solicitud, el servidor debe hacer lo siguiente:
- Determina el RP para
client_id
. - Responde con los metadatos del cliente.
Las propiedades del extremo de metadatos del cliente incluyen las siguientes:
Propiedad | Descripción |
---|---|
privacy_policy_url (opcional) |
URL de la política de privacidad del RP |
terms_of_service_url (opcional) |
URL de las Condiciones del Servicio del RP |
icons (opcional) |
Array de objetos, como [{ "url": "https://rp.example/rp-icon.ico", "size": 40}] |
El navegador espera una respuesta JSON del extremo:
{
"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
}]
}
El navegador consume los metadatos del cliente que se muestran y no estarán disponibles para la RP.
URL de acceso
Este extremo se usa para permitir que el usuario acceda a la IdP.
Con la API de Login Status, la AC debe informar el estado de acceso del usuario al navegador. Sin embargo, el estado podría estar desincronizado, por ejemplo, cuando vence la sesión. En ese caso, el navegador puede permitir que el usuario acceda al IdP de forma dinámica a través de la URL de la página de acceso especificada con el login_url
del archivo de configuración de idp.
El diálogo de FedCM muestra un mensaje que sugiere un acceso, como se muestra en la siguiente imagen.
![A](https://developers.google.cn/static/privacy-sandbox/assets/images/blog/fedcm-120-1.png?hl=es-419)
Cuando el usuario hace clic en el botón Continuar, el navegador abre una ventana emergente para la página de acceso de la AC.
![Ejemplo de diálogo de FedCM](https://developers.google.cn/static/privacy-sandbox/assets/images/fedcm-dialog-example.png?hl=es-419)
El diálogo es una ventana de navegador normal que tiene cookies propias. Lo que ocurra dentro del diálogo depende del IdP, y no hay controladores de ventana disponibles para realizar una solicitud de comunicación entre dominios a la página de la RP. Después de que el usuario acceda, el IdP debe hacer lo siguiente:
- Envía el encabezado
Set-Login: logged-in
o llama a la API denavigator.login.setStatus("logged-in")
para informarle al navegador que el usuario accedió. - Llama a
IdentityProvider.close()
para cerrar el diálogo.
Informa al navegador sobre el estado de acceso del usuario
La API de Login Status es un mecanismo en el que un sitio web, en especial un IdP, informa al navegador el estado de acceso del usuario en el IdP. Con esta API, el navegador puede reducir las solicitudes innecesarias a la IdP y mitigar posibles ataques de sincronización.
Los IdPs pueden indicar el estado de acceso del usuario al navegador enviando un encabezado HTTP o llamando a una API de JavaScript cuando el usuario accede al IdP o cuando sale de todas sus cuentas de IdP. Para cada IdP (identificado por su URL de configuración), el navegador mantiene una variable de tres estados que representa el estado de acceso con los siguientes valores posibles:
logged-in
logged-out
unknown
(predeterminada)
Estado de acceso | Descripción |
---|---|
logged-in |
Cuando el estado de acceso del usuario se establece en logged-in , el RP que llama a FedCM realiza solicitudes al extremo de cuentas de la AC y muestra las cuentas disponibles al usuario en el diálogo de FedCM. |
logged-out |
Cuando el estado de acceso del usuario es logged-out , la llamada a FedCM falla de forma silenciosa sin realizar una solicitud al extremo de cuentas de la AC. |
unknown (predeterminada) |
El estado unknown se establece antes de que el IdP envíe un indicador con la API de Login Status. Cuando el estado es unknown , el navegador realiza una solicitud al extremo de cuentas del IdP y actualiza el estado según la respuesta del extremo de cuentas. |
Para indicar que el usuario accedió, envía un encabezado HTTP Set-Login: logged-in
en una navegación de nivel superior o una solicitud de subrecurso del mismo sitio en el origen del IdP:
Set-Login: logged-in
Como alternativa, llama al método navigator.login.setStatus('logged-in')
de JavaScript desde el origen de la IdP en una navegación de nivel superior:
navigator.login.setStatus('logged-in')
El estado de acceso del usuario se establecerá como logged-in
.
Para indicar que el usuario salió de todas sus cuentas, envía un encabezado HTTP Set-Login: logged-out
en una navegación de nivel superior o una solicitud de subrecurso del mismo sitio en el origen del IdP:
Set-Login: logged-out
Como alternativa, llama a la API de JavaScript navigator.login.setStatus('logged-out')
desde el origen de la IdP en una navegación de nivel superior:
navigator.login.setStatus('logged-out')
El estado de acceso del usuario se establecerá como logged-out
.
El estado unknown
se establece antes de que el IdP envíe un indicador con la API de Login Status. El navegador envía una solicitud al extremo de cuentas del IdP y actualiza el estado según la respuesta del extremo de cuentas:
- Si el extremo muestra una lista de cuentas activas, actualiza el estado a
logged-in
y abre el diálogo de FedCM para mostrar esas cuentas. - Si el extremo no muestra ninguna cuenta, actualiza el estado a
logged-out
y falla la llamada a FedCM.
Permite que el usuario acceda a través de un flujo de acceso dinámico
Aunque el IdP sigue informando el estado de acceso del usuario al navegador, podría estar desincronizado, por ejemplo, cuando vence la sesión. El navegador intenta enviar una solicitud con credenciales al extremo de cuentas cuando el estado de acceso es logged-in
, pero el servidor no muestra ninguna cuenta porque la sesión ya no está disponible. En ese caso, el navegador puede permitir que el usuario acceda de forma dinámica al IdP a través de una ventana emergente.