Secure Data Connect con autorización y certificación

Firebase Data Connect proporciona una seguridad sólida del cliente con lo siguiente:

  • Autorización de clientes web y para dispositivos móviles
  • Controles de autorización individuales a nivel de la consulta y la mutación
  • Certificación de la app con Firebase App Check

Data Connect extiende esta seguridad con lo siguiente:

  • Autorización del servidor
  • Seguridad del usuario del proyecto de Firebase y de Cloud SQL con IAM

Autoriza las consultas y mutaciones del cliente

Data Connect está completamente integrado en Firebase Authentication, por lo que puedes usar datos enriquecidos sobre los usuarios que acceden a tus datos (autenticación) en tu diseño para saber a qué datos pueden acceder esos usuarios (autorización).

Data Connect proporciona una directiva @auth para las consultas y las mutaciones que te permite establecer el nivel de autenticación necesario para autorizar la operación. En esta guía, se presenta la directiva @auth con ejemplos.

Además, Data Connect admite la ejecución de consultas incorporadas en las mutaciones, de modo que puedas recuperar criterios de autorización adicionales que almacenaste en tu base de datos y usar esos criterios en las directivas @check para decidir si se autorizan las mutaciones de cierre. En este caso de autorización, la directiva @redact te permite controlar si los resultados de la consulta se devuelven a los clientes en el protocolo de red y si se omite la consulta incorporada en los SDKs generados. Consulta la introducción a estas directivas, con ejemplos.

Comprende la directiva @auth

Puedes parametrizar la directiva @auth para que siga uno de varios niveles de acceso preestablecidos que abarcan muchas situaciones de acceso comunes. Estos niveles van desde PUBLIC (que permite consultas y mutaciones de todos los clientes sin autenticación de ningún tipo) hasta NO_ACCESS (que no permite consultas ni mutaciones fuera de los entornos de servidor privilegiados con el SDK de Firebase Admin). Cada uno de estos niveles se correlaciona con los flujos de autenticación que proporciona Firebase Authentication.

Nivel Definición
PUBLIC Cualquier persona puede ejecutar la operación con o sin autenticación.
PUBLIC Cualquier persona puede ejecutar la operación con o sin autenticación.
USER_ANON Cualquier usuario identificado, incluidos los que accedieron de forma anónima con Firebase Authentication, tiene autorización para realizar la consulta o la mutación.
USER Cualquier usuario que haya accedido con Firebase Authentication está autorizado a realizar la consulta o la mutación, excepto los usuarios de acceso anónimo.
USER_EMAIL_VERIFIED Cualquier usuario que haya accedido con Firebase Authentication con una dirección de correo electrónico verificada está autorizado para realizar la consulta o la mutación.
NO_ACCESS Esta operación no se puede ejecutar fuera de un contexto de SDK de Admin.

Con estos niveles de acceso preestablecidos como punto de partida, puedes definir verificaciones de autorización complejas y sólidas en la directiva @auth con filtros where y expresiones de Common Expression Language (CEL) que se evalúan en el servidor.

Usa la directiva @auth para implementar situaciones de autorización comunes

Los niveles de acceso predeterminados son el punto de partida para la autorización.

El nivel de acceso USER es el nivel básico más útil para comenzar.

El acceso completamente seguro se basará en el nivel USER, además de los filtros y las expresiones que verifican los atributos de los usuarios, los atributos de los recursos, los roles y otras verificaciones. Los niveles USER_ANON y USER_EMAIL_VERIFIED son variaciones del caso USER.

La sintaxis de expresión te permite evaluar datos con un objeto auth que representa datos de autenticación pasados con operaciones, tanto datos estándar en tokens de autenticación como datos personalizados en tokens. Para obtener la lista de campos disponibles en el objeto auth, consulta la sección de referencia.

Por supuesto, hay casos de uso en los que PUBLIC es el nivel de acceso correcto para comenzar. Una vez más, un nivel de acceso siempre es un punto de partida, y se necesitan filtros y expresiones adicionales para una seguridad sólida.

En esta guía, se proporcionan ejemplos de cómo compilar en USER y PUBLIC.

Un ejemplo motivador

Los siguientes ejemplos de prácticas recomendadas se refieren al siguiente esquema de una plataforma de blogs con cierto contenido bloqueado detrás de un plan de pagos.

Es probable que una plataforma de este tipo modele Users yPosts.

type User @table(key: "uid") {
  uid: String!
  name: String
  birthday: Date
  createdAt: Timestamp! @default(expr: "request.time")
}

type Post @table {
  author: User!
  text: String!
  # "one of 'draft', 'public', or 'pro'"
  visibility: String! @default(value: "draft")
  # "the time at which the post should be considered published. defaults to
  # immediately"
  publishedAt: Timestamp! @default(expr: "request.time")
  createdAt: Timestamp! @default(expr: "request.time")
  updatedAt: Timestamp! @default(expr: "request.time")
}

Recursos que pertenecen al usuario

Firebase recomienda que escribas filtros y expresiones que prueben la propiedad del usuario de un recurso, en los siguientes casos, la propiedad de Posts.

En los siguientes ejemplos, los datos de los tokens de autenticación se leen y comparan con expresiones. El patrón típico es usar expresiones como where: {authorUid: {eq_expr: "auth.uid"}} para comparar un authorUid almacenado con el auth.uid (ID de usuario) que se pasa en el token de autenticación.

Crear

Esta práctica de autorización comienza con la adición del auth.uid del token de autenticación a cada Post nuevo como un campo authorUid para permitir la comparación en las pruebas de autorización de subsecuentes.

# Create a new post as the current user
mutation CreatePost($text: String!, $visibility: String) @auth(level: USER) {
  post_insert(data: {
    # set the author's uid to the current user uid
    authorUid_expr: "auth.uid"
    text: $text
    visibility: $visibility
  })
}
Actualizar

Cuando un cliente intenta actualizar un Post, puedes probar el auth.uid que se pasó con el authorUid almacenado.

# Update one of the current user's posts
mutation UpdatePost($id: UUID!, $text: String, $visibility: String) @auth(level:USER) {
  post_update(
    # only update posts whose author is the current user
    first: { where: {
      id: {eq: $id}
      authorUid: {eq_expr: "auth.uid"}
    }}
    data: {
      text: $text
      visibility: $visibility
      # insert the current server time for updatedAt
      updatedAt_expr: "request.time"
    }
  )
}
Borrar

Se usa la misma técnica para autorizar operaciones de eliminación.

# Delete one of the current user's posts
mutation DeletePost($id: UUID!) @auth(level: USER) {
  post_delete(
    # only delete posts whose author is the current user
    first: { where: {
      id: {eq: $id}
      authorUid: {eq_expr: "auth.uid"}
    }}
  )
}
# Common display information for a post
fragment DisplayPost on Post {
  id, text, createdAt, updatedAt
  author { uid, name }
}
Lista
# List all posts belonging to the current user
query ListMyPosts @auth(level: USER) {
  posts(where: {
    userUid: {eq_expr: "auth.uid"}
  }) {
    # See the fragment above
    ...DisplayPost
    # also show visibility since it is user-controlled
    visibility
  }
}
Obtener
# Get a post only if it belongs to the current user
query GetMyPost($id: UUID!) @auth(level: USER) {
  post(key: {id: $id},
    first: {where: {
      id: {eq: $id}
      authorUid: {eq_expr: "auth.uid"}}
      }}, {
      # See the fragment above
      ...DisplayPost
      # also show visibility since it is user-controlled
      visibility
  }
}

Filtrar datos

El sistema de autorización de Data Connect te permite escribir filtros sofisticados combinados con niveles de acceso preestablecidos, como PUBLIC, y con el uso de datos de tokens de autenticación.

El sistema de autorización también te permite usar solo expresiones, sin un nivel de acceso básico, como se muestra en algunos de los siguientes ejemplos.

Filtrar por atributos de recursos

Aquí, la autorización no se basa en tokens de autenticación, ya que el nivel de seguridad básico se establece en PUBLIC. Sin embargo, podemos establecer explícitamente registros en nuestra base de datos como adecuados para el acceso público. Supongamos que tenemos Post registros en nuestra base de datos con visibility establecido como “público”.

# List all posts marked as 'public' visibility
query ListPublicPosts @auth(level: PUBLIC) {
  posts(where: {
    # Test that visibility is "public"
    visibility: {eq: "public"}
    # Only display articles that are already published
    publishedAt: {lt_expr: "request.time"}
  }) {
    # see the fragment above
    ...DisplayPost
  }
}
Filtrar por reclamos del usuario

Aquí, supongamos que configuraste reclamos de usuario personalizados que pasan tokens de autenticación para identificar a los usuarios en un plan "pro" para tu app, marcado con un campo auth.token.plan en el token de autenticación. Tus expresiones se pueden probar en este campo.

# List all public or pro posts, only permitted if user has "pro" plan claim
query ProListPosts @auth(expr: "auth.token.plan == 'pro'") {
  posts(where: {
    # display both public posts and "pro" posts
    visibility: {in: ['public', 'pro']},
    # only display articles that are already published
    publishedAt: {lt_expr: "request.time"},
  }) {
    # see the fragment above
    ...DisplayPost
    # show visibility so pro users can see which posts are pro\
    visibility
  }
}
Filtrar por orden + límite

También es posible que hayas establecido visibility en los registros Post para identificar que son contenido disponible para usuarios "pro", pero, para una vista previa o una ficha de datos de avance, limita aún más la cantidad de registros que se muestran.

# Show 2 oldest Pro post as a preview
query ProTeaser @auth(level: USER) {
  posts(
    where: {
      # show only pro posts
      visibility: {eq: "pro"}
      # that have already been published more than 30 days ago
      publishedAt: {lt_time: {now: true, sub: {days: 30}}}
    },
    # order by publish time
    orderBy: [{publishedAt: DESC}],
    # only return two posts
    limit: 2
  ) {
    # See the fragment above
    ...DisplayPost
  }
}
Filtrar por función

Si tu reclamo personalizado define un rol admin, puedes probar y autorizar las operaciones según corresponda.

# List all posts unconditionally iff the current user has an admin claim
query AdminListPosts @auth(expr: "auth.token.admin == true") {
  posts { ...DisplayPost }
}

Comprende las directivas @check y @redact

La directiva @check verifica que los campos especificados estén presentes en los resultados de la consulta. Se usa una expresión de Common Expression Language (CEL) para probar los valores de los campos. El comportamiento predeterminado de la directiva es verificar y rechazar los nodos con valores null.

La directiva @redact oculta una parte de la respuesta del cliente. Los campos ocultos aún se evalúan en busca de efectos secundarios (incluidos los cambios de datos y @check), y los resultados aún están disponibles para pasos posteriores en las expresiones CEL.

En Data Connect, las directivas @check y @redact se usan con mayor frecuencia en el contexto de las verificaciones de autorización. Consulta la discusión sobre la búsqueda de datos de autorización.

Agrega las directivas @check y @redact para buscar datos de autorización

Un caso de uso de autorización común implica almacenar roles de autorización personalizados en tu base de datos, por ejemplo, en una tabla de permisos especiales, y usar esos roles para autorizar mutaciones para crear, actualizar o borrar datos.

Con las búsquedas de datos de autorización, puedes consultar roles según un userID y usar expresiones CEL para decidir si la mutación está autorizada. Por ejemplo, quizás desees escribir una mutación UpdateMovieTitle que permita que un cliente autorizado actualice los títulos de las películas.

Para el resto de esta discusión, supongamos que la base de datos de la app de opiniones de películas almacena un rol de autorización en una tabla MoviePermission.

# MoviePermission
# Suppose a user has an authorization role with respect to records in the Movie table
type MoviePermission @table(key: ["doc", "userId"]) {
  movie: Movie! # implies another field: movieId: UUID!
  userId: String! # Can also be a reference to a User table, doesn't matter
  role: String!
}

En el siguiente ejemplo de implementación, la mutación UpdateMovieTitle incluye un campo query para recuperar datos de MoviePermission y las siguientes directivas para garantizar que la operación sea segura y sólida:

  • Una directiva @transaction para garantizar que todas las consultas y verificaciones de autorización se completen o fallen de forma automática.
  • La directiva @redact para omitir los resultados de la consulta de la respuesta, lo que significa que nuestra verificación de autorización se realiza en el servidor Data Connect, pero los datos sensibles no se exponen al cliente.
  • Un par de directivas @check para evaluar la lógica de autorización en los resultados de la consulta, como probar que un ID de usuario determinado tenga un rol adecuado para realizar modificaciones.

mutation UpdateMovieTitle($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
  # Step 1: Query and check
  query @redact {
    moviePermission( # Look up a join table called MoviePermission with a compound key.
      key: {movieId: $movieId, userId_expr: "auth.uid"}
    # Step 1a: Use @check to test if the user has any role associated with the movie
    # Here the `this` binding refers the lookup result, i.e. a MoviePermission object or null
    # The `this != null` expression could be omitted since rejecting on null is default behavior
    ) @check(expr: "this != null", message: "You do not have access to this movie") {
      # Step 1b: Check if the user has the editor role for the movie
      # Next we execute another @check; now `this` refers to the contents of the `role` field
      role @check(expr: "this == 'editor'", message: "You must be an editor of this movie to update title")
    }
  }
  # Step 2: Act
  movie_update(id: $movieId, data: {
    title: $newTitle
  })
}

Antipatrones que se deben evitar en la autorización

En la sección anterior, se describen los patrones que se deben seguir cuando se usa la directiva @auth.

También debes tener en cuenta los antipatrones importantes que debes evitar.

Evita pasar IDs de atributos de usuario y parámetros de tokens de autenticación en los argumentos de consulta y mutación

Firebase Authentication es una herramienta potente para presentar flujos de autenticación y capturar de forma segura datos de autenticación, como IDs de usuario registrados y varios campos almacenados en tokens de autenticación.

No se recomienda pasar IDs de usuario y datos de tokens de autenticación en los argumentos de consulta y mutación.

# Antipattern!
# This incorrectly allows any user to view any other user's posts
query AllMyPosts($userId: String!) @auth(level: USER) {
  posts(where: {authorUid: {eq: $userId}}) {
    id, text, createdAt
  }
}

Evita usar el nivel de acceso USER sin ningún filtro

Como se mencionó varias veces en la guía, los niveles de acceso principales, como USER, USER_ANON y USER_EMAIL_VERIFIED, son referencias y puntos de partida para las verificaciones de autorización, que se mejorarán con filtros y expresiones. El uso de estos niveles sin un filtro o una expresión correspondiente que verifique qué usuario realiza la solicitud es, en esencia, equivalente al uso del nivel PUBLIC.

# Antipattern!
# This incorrectly allows any user to view all documents
query ListDocuments @auth(level: USER) {
  documents {
    id
    title
    text
  }
}

Evita usar el nivel de acceso PUBLIC o USER para crear prototipos

Para acelerar el desarrollo, puede ser tentador configurar todas las operaciones en el nivel de acceso PUBLIC o USER sin más mejoras para autorizar todas las operaciones y permitirte probar tu código rápidamente.

Cuando hayas creado prototipos muy iniciales de esta manera, comienza a cambiar de NO_ACCESS a la autorización lista para producción con los niveles PUBLIC y USER. Sin embargo, no los implementes como PUBLIC o USER sin agregar lógica adicional, como se muestra en esta guía.

# Antipattern!
# This incorrectly allows anyone to delete any post
mutation DeletePost($id: UUID!) @auth(level: PUBLIC) {
  post: post_delete(
    id: $id,
  )
}

Usa Firebase App Check para la certificación de apps

La autenticación y la autorización son componentes fundamentales de la seguridad de Data Connect. La autenticación y la autorización combinadas con la certificación de apps conforman una solución de seguridad muy sólida.

Con la certificación a través de Firebase App Check, los dispositivos que ejecutan tu app usarán un proveedor de certificación de apps o de dispositivos que certifique que las operaciones de Data Connect se originan en tu app auténtica y que las solicitudes se originan en un dispositivo auténtico y no adulterado. Esta certificación se adjunta a cada solicitud que tu app realiza a Data Connect.

Para obtener información sobre cómo habilitar App Check para Data Connect y, luego, incluir su SDK cliente en tu app, consulta la descripción general de App Check.

Niveles de autenticación para la directiva @auth(level)

En la siguiente tabla, se enumeran todos los niveles de acceso estándar y sus equivalentes de CEL. Los niveles de autenticación se enumeran de forma amplia a estrecha, y cada nivel abarca a todos los usuarios que coinciden con los siguientes niveles.

Nivel Definición
PUBLIC Cualquier persona puede ejecutar la operación con o sin autenticación.

Consideraciones: Cualquier usuario puede leer o modificar los datos. Firebase recomienda este nivel de autorización para los datos que se pueden explorar públicamente, como las fichas de productos o de contenido multimedia. Consulta los ejemplos y las alternativas de las prácticas recomendadas.

Equivalente a @auth(expr: "true")

Los filtros y las expresiones @auth no se pueden usar en combinación con este nivel de acceso. Cualquier expresión de este tipo fallará con un error de solicitud incorrecta 400.
USER_ANON Cualquier usuario identificado, incluidos los que accedieron de forma anónima con Firebase Authentication, tiene autorización para realizar la consulta o la mutación.

Nota: USER_ANON es un superconjunto de USER.

Consideraciones: Ten en cuenta que debes diseñar cuidadosamente tus consultas y mutaciones para este nivel de autorización. Este nivel permite que el usuario acceda de forma anónima (acceso automático vinculado solo a un dispositivo del usuario) con Authentication y, por sí solo, no realiza otras verificaciones, por ejemplo, si los datos pertenecen al usuario. Consulta los ejemplos y las alternativas de las prácticas recomendadas.

Dado que los flujos de acceso anónimo Authentication emiten un uid, el nivel USER_ANON es equivalente a
. @auth(expr: "auth.uid != nil")
USER Cualquier usuario que haya accedido con Firebase Authentication está autorizado a realizar la consulta o la mutación, excepto los usuarios de acceso anónimo.

Consideraciones: Ten en cuenta que debes diseñar cuidadosamente tus consultas y mutaciones para este nivel de autorización. Este nivel solo verifica que el usuario haya accedido con Authentication y, por sí solo, no realiza otras verificaciones, por ejemplo, si los datos pertenecen al usuario. Consulta los ejemplos y las alternativas de las prácticas recomendadas.

Equivale a @auth(expr: "auth.uid != nil && auth.token.firebase.sign_in_provider != 'anonymous'")".
USER_EMAIL_VERIFIED Cualquier usuario que haya accedido con Firebase Authentication con una dirección de correo electrónico verificada está autorizado para realizar la consulta o la mutación.

Consideraciones: Dado que la verificación por correo electrónico se realiza con Authentication, se basa en un método Authentication más sólido, por lo que este nivel proporciona seguridad adicional en comparación con USER o USER_ANON. Este nivel solo verifica que el usuario haya accedido con Authentication con un correo electrónico verificado y no realiza otras verificaciones por sí solo, por ejemplo, si los datos pertenecen al usuario. Consulta los ejemplos y las alternativas de las prácticas recomendadas.

Equivale a @auth(expr: "auth.uid != nil && auth.token.email_verified")".
NO_ACCESS Esta operación no se puede ejecutar fuera de un contexto de SDK de Admin.

Equivale a @auth(expr: "false").

Referencia de CEL para @auth(expr) y @check(expr)

Como se muestra en los ejemplos de otras partes de esta guía, puedes y debes usar expresiones definidas en Common Expression Language (CEL) para controlar la autorización de Data Connect con las directivas @auth(expr:) y @check.

En esta sección, se aborda la sintaxis de CEL relevante para crear expresiones para estas directivas.

La información de referencia completa de CEL se proporciona en la especificación de CEL.

Prueba las variables que se pasan en las consultas y mutaciones

La sintaxis de @auth(expr) te permite acceder a variables y probarlas desde consultas y mutaciones.

Por ejemplo, puedes incluir una variable de operación, como $status, con vars.status.

mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")

Datos disponibles para las expresiones

Las expresiones CEL @auth(expr:) y @check(expr:) pueden evaluar lo siguiente:

  • request.operationName
  • vars (alias de request.variables)
  • auth (alias de request.auth)

Además, las expresiones @check(expr:) pueden evaluar lo siguiente:

  • this (el valor del campo actual)

El objeto request.operationName

El objeto request.operarationName almacena el tipo de operación, ya sea una consulta o una mutación.

El objeto vars

El objeto vars permite que tus expresiones accedan a todas las variables que se pasan en tu consulta o mutación.

Puedes usar vars.<variablename> en una expresión como alias para el request.variables.<variablename> completamente calificado:

# The following are equivalent
mutation StringType($v: String!) @auth(expr: "vars.v == 'hello'")
mutation StringType($v: String!) @auth(expr: "request.variables.v == 'hello'")

El objeto auth

Authentication identifica a los usuarios que solicitan acceso a tus datos y proporciona esa información como un objeto en el que puedes basarte en tus expresiones.

En tus filtros y expresiones, puedes usar auth como alias para request.auth.

El objeto auth contiene la siguiente información:

  • uid: Un ID de usuario único, asignado al usuario solicitante.
  • token: Un mapa de valores recopilados por Authentication.

Para obtener más detalles sobre el contenido de auth.token, consulta Datos en los tokens de autenticación.

La vinculación de this

La vinculación this se evalúa como el campo al que se adjunta la directiva @check. En un caso básico, puedes evaluar los resultados de la consulta de un solo valor.

mutation UpdateMovieTitle($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
  # Step 1: Query and check
  query @redact {
    moviePermission( # Look up a join table called MoviePermission with a compound key.
      key: {movieId: $movieId, userId_expr: "auth.uid"}
    ) {
      # Check if the user has the editor role for the movie. `this` is the string value of `role`.
      # If the parent moviePermission is null, the @check will also fail automatically.
      role @check(expr: "this == 'editor'", message: "You must be an editor of this movie to update title")
    }
  }
  # Step 2: Act
  movie_update(id: $movieId, data: {
    title: $newTitle
  })
}

Si el campo que se muestra ocurre varias veces porque cualquier ancestro es una lista, cada ocurrencia se prueba con this vinculado a cada valor.

Para cualquier ruta determinada, si un ancestro es null o [], no se llegará al campo y se omitirá la evaluación de CEL para esa ruta. En otras palabras, la evaluación solo se realiza cuando this es null o no es null, pero nunca es undefined.

Cuando el campo en sí es una lista o un objeto, this sigue la misma estructura (incluidos todos los descendientes seleccionados en el caso de los objetos), como se ilustra en el siguiente ejemplo.

mutation UpdateMovieTitle2($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
  # Step 1: Query and check
  query {
    moviePermissions( # Now we query for a list of all matching MoviePermissions.
      where: {movieId: {eq: $movieId}, userId: {eq_expr: "auth.uid"}}
    # This time we execute the @check on the list, so `this` is the list of objects.
    # We can use the `.exists` macro to check if there is at least one matching entry.
    ) @check(expr: "this.exists(p, p.role == 'editor')", message: "You must be an editor of this movie to update title") {
      role
    }
  }
  # Step 2: Act
  movie_update(id: $movieId, data: {
    title: $newTitle
  })
}

Sintaxis de expresión compleja

Puedes escribir expresiones más complejas si las combinas con los operadores && y ||.

mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")

En la siguiente sección, se describen todos los operadores disponibles.

Operadores y prioridad de operadores

Usa la siguiente tabla como referencia para los operadores y su prioridad correspondiente.

Dadas las expresiones arbitrarias a y b, un campo f y un índice i.

Operador Descripción Asociatividad
a[i] a() a.f Acceso a índice, llamada o campo de izquierda a derecha
!a -a Negación unaria De derecha a izquierda
a/b a%b a*b Operadores multiplicativos de izquierda a derecha
a+b a-b Operadores aditivos de izquierda a derecha
a>b a>=b a<b a<=b Operadores relacionales de izquierda a derecha
a in b Existencia en lista o mapa de izquierda a derecha
type(a) == t Comparación de tipos, en la que t puede ser bool, int, float, number, string, list, map, timestamp o duration de izquierda a derecha
a==b a!=b Operadores de comparación de izquierda a derecha
a && b Condicional AND de izquierda a derecha
a || b Condicional OR de izquierda a derecha
a ? true_value : false_value Expresión ternaria de izquierda a derecha

Datos en los tokens de autenticación

El objeto auth.token puede contener los siguientes valores:

Campo Descripción
email Dirección de correo electrónico asociada con la cuenta, si está presente.
email_verified true si el usuario verificó que tiene acceso a la dirección email. Algunos proveedores verifican automáticamente las direcciones de correo electrónico de su propiedad.
phone_number Número de teléfono asociado con la cuenta, si está presente.
name Nombre visible del usuario, si se configuró.
sub UID de Firebase del usuario. Es único dentro de un proyecto.
firebase.identities Diccionario de todas las identidades asociadas con la cuenta del usuario. Las claves del diccionario pueden ser cualquiera de las siguientes: email, phone, google.com, facebook.com, github.com y twitter.com. Los valores del diccionario son arreglos de identificadores únicos para cada proveedor de identidad asociado con la cuenta. Por ejemplo, auth.token.firebase.identities["google.com"][0] contiene el primer ID de usuario de Google asociado a la cuenta.
firebase.sign_in_provider Proveedor de acceso utilizado para obtener este token. Puede ser una de las siguientes strings: custom, password, phone, anonymous, google.com, facebook.com, github.com y twitter.com.
firebase.tenant El tenantId asociado con la cuenta, si está presente Por ejemplo, tenant2-m6tyz

Campos adicionales en los tokens de ID de JWT

También puedes acceder a los siguientes campos auth.token:

Reclamaciones de tokens personalizados
alg Algoritmo "RS256"
iss Emisor Dirección de correo electrónico de la cuenta de servicio del proyecto
sub Asunto Dirección de correo electrónico de la cuenta de servicio del proyecto
aud Público "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Hora de emisión Hora actual, en segundos transcurridos desde la época UNIX
exp Hora de vencimiento Hora de vencimiento del token, en segundos transcurridos desde la época UNIX Puede ser un máximo de 3,600 segundos más tarde de iat.
Nota: Ten en cuenta que esto solo controla la hora de vencimiento del token personalizado en sí. Sin embargo, cuando haces que un usuario acceda con signInWithCustomToken(), su acceso al dispositivo se mantendrá hasta que esa sesión deje de ser válida o el usuario la cierre.
<claims> (opcional) Son reclamos personalizados opcionales que se incluyen en el token, al que se puede acceder a través de auth.token (o request.auth.token) en expresiones. Por ejemplo, si creas un reclamo personalizado adminClaim, puedes acceder a él con auth.token.adminClaim.

Próximos pasos