Sécuriser Data Connect avec l'autorisation et l'attestation

Firebase Data Connect offre une sécurité côté client robuste avec:

  • Autorisation des clients mobiles et Web
  • Contrôles d'autorisation individuels au niveau des requêtes et des mutations
  • Attestation d'application avec Firebase App Check.

Data Connect étend cette sécurité avec:

  • Autorisation côté serveur
  • Sécurité des projets Firebase et des utilisateurs Cloud SQL avec IAM

Autoriser les requêtes et les mutations client

Data Connect est entièrement intégré à Firebase Authentication. Vous pouvez donc utiliser des données riches sur les utilisateurs qui accèdent à vos données (authentification) dans votre conception pour déterminer les données auxquelles ces utilisateurs peuvent accéder (autorisation).

Data Connect fournit une directive @auth pour les requêtes et les mutations qui vous permet de définir le niveau d'authentification requis pour autoriser l'opération. Ce guide présente la directive @auth, avec des exemples.

De plus, Data Connect permet d'exécuter des requêtes intégrées aux mutations. Vous pouvez ainsi récupérer des critères d'autorisation supplémentaires que vous avez stockés dans votre base de données et les utiliser dans des directives @check pour déterminer si les mutations englobantes sont autorisées. Pour ce cas d'autorisation, la directive @redact vous permet de contrôler si les résultats de la requête sont renvoyés aux clients dans le protocole filaire et si la requête intégrée est omise dans les SDK générés. Consultez l'introduction à ces directives, avec des exemples.

Comprendre la directive @auth

Vous pouvez paramétrer la directive @auth pour suivre l'un des niveaux d'accès prédéfinis qui couvrent de nombreux scénarios d'accès courants. Ces niveaux vont de PUBLIC (qui autorise les requêtes et les mutations de tous les clients sans aucune authentification) à NO_ACCESS (qui interdit les requêtes et les mutations en dehors des environnements de serveurs privilégiés à l'aide du SDK Admin Firebase). Chacun de ces niveaux est corrélé aux flux d'authentification fournis par Firebase Authentication.

Niveau Définition
PUBLIC L'opération peut être exécutée par n'importe qui, avec ou sans authentification.
PUBLIC L'opération peut être exécutée par n'importe qui, avec ou sans authentification.
USER_ANON Tout utilisateur identifié, y compris ceux qui se sont connectés de manière anonyme avec Firebase Authentication, est autorisé à effectuer la requête ou la mutation.
USER Tout utilisateur qui s'est connecté avec Firebase Authentication est autorisé à effectuer la requête ou la mutation, à l'exception des utilisateurs anonymes.
USER_EMAIL_VERIFIED Tout utilisateur qui s'est connecté avec Firebase Authentication avec une adresse e-mail validée est autorisé à effectuer la requête ou la mutation.
NO_ACCESS Cette opération ne peut pas être exécutée en dehors d'un contexte de SDK Admin.

En utilisant ces niveaux d'accès prédéfinis comme point de départ, vous pouvez définir des vérifications d'autorisation complexes et robustes dans la directive @auth à l'aide de filtres where et d'expressions CEL (Common Expression Language) évaluées sur le serveur.

Utiliser la directive @auth pour implémenter des scénarios d'autorisation courants

Les niveaux d'accès prédéfinis constituent le point de départ de l'autorisation.

Le niveau d'accès USER est le niveau de base le plus utilisé pour commencer.

L'accès entièrement sécurisé s'appuie sur le niveau USER, ainsi que sur des filtres et des expressions qui vérifient les attributs utilisateur, les attributs de ressources, les rôles et d'autres vérifications. Les niveaux USER_ANON et USER_EMAIL_VERIFIED sont des variantes du cas USER.

La syntaxe d'expression vous permet d'évaluer les données à l'aide d'un objet auth représentant les données d'authentification transmises avec les opérations, à la fois des données standards dans les jetons d'authentification et des données personnalisées dans les jetons. Pour obtenir la liste des champs disponibles dans l'objet auth, consultez la section de référence.

Il existe bien sûr des cas d'utilisation pour lesquels PUBLIC est le bon niveau d'accès de départ. Là encore, un niveau d'accès est toujours un point de départ, et des filtres et des expressions supplémentaires sont nécessaires pour une sécurité robuste.

Ce guide fournit désormais des exemples de compilation sur USER et PUBLIC.

Un exemple motivant

Les exemples de bonnes pratiques suivants font référence au schéma suivant pour une plate-forme de blogs dont certains contenus sont verrouillés derrière un plan de paiement.

Une telle plate-forme modéliserait probablement Users et Posts.

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

Ressources appartenant à l'utilisateur

Firebase vous recommande d'écrire des filtres et des expressions qui testent la propriété d'une ressource par l'utilisateur, dans les cas suivants, la propriété de Posts.

Dans les exemples suivants, les données des jetons d'authentification sont lues et comparées à l'aide d'expressions. Le modèle typique consiste à utiliser des expressions telles que where: {authorUid: {eq_expr: "auth.uid"}} pour comparer un authorUid stocké à l'auth.uid (ID utilisateur) transmis dans le jeton d'authentification.

Créer

Cette pratique d'autorisation commence par ajouter le auth.uid du jeton d'autorisation à chaque nouveau Post en tant que champ authorUid pour permettre la comparaison dans les tests d'autorisation de séquences.

# 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
  })
}
Mettre à jour

Lorsqu'un client tente de mettre à jour un Post, vous pouvez tester le auth.uid transmis par rapport au authorUid stocké.

# 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"
    }
  )
}
Supprimer

La même technique est utilisée pour autoriser les opérations de suppression.

# 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 }
}
Liste
# 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
  }
}
Get
# 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
  }
}

Filtrer les données

Le système d'autorisation de Data Connect vous permet d'écrire des filtres sophistiqués combinés à des niveaux d'accès prédéfinis tels que PUBLIC, ainsi qu'en utilisant les données des jetons d'authentification.

Le système d'autorisation vous permet également d'utiliser uniquement des expressions, sans niveau d'accès de base, comme illustré dans certains des exemples suivants.

Filtrer par attributs de ressource

Ici, l'autorisation n'est pas basée sur des jetons d'authentification, car le niveau de sécurité de base est défini sur PUBLIC. Toutefois, nous pouvons définir explicitement les enregistrements de notre base de données comme étant adaptés à un accès public. Supposons que nous ayons Post enregistrements dans notre base de données, avec visibility défini sur "public".

# 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
  }
}
Filtrer par revendications utilisateur

Ici, supposons que vous ayez configuré des revendications utilisateur personnalisées qui transmettent des jetons d'authentification pour identifier les utilisateurs dans un forfait "pro" pour votre application, signalés par un champ auth.token.plan dans le jeton d'authentification. Vos expressions peuvent effectuer des tests sur ce champ.

# 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
  }
}
Filtrer par ordre et limite

Vous pouvez également avoir défini visibility dans les enregistrements Post pour identifier les contenus disponibles pour les utilisateurs "pro", mais pour une prévisualisation ou une fiche d'aperçu des données, limitez davantage le nombre d'enregistrements renvoyés.

# 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
  }
}
Filtrer par rôle

Si votre revendication personnalisée définit un rôle admin, vous pouvez tester et autoriser les opérations en conséquence.

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

Comprendre les directives @check et @redact

La directive @check vérifie que les champs spécifiés sont présents dans les résultats de la requête. Une expression CEL (Common Expression Language) permet de tester les valeurs des champs. Le comportement par défaut de la directive consiste à rechercher et à rejeter les nœuds avec une valeur null.

La directive @redact masque une partie de la réponse du client. Les champs masqués sont toujours évalués pour détecter les effets secondaires (y compris les modifications de données et @check), et les résultats sont toujours disponibles pour les étapes ultérieures des expressions CEL.

Dans Data Connect, les directives @check et @redact sont le plus souvent utilisées dans le contexte des vérifications d'autorisation. Consultez la discussion sur la recherche de données d'autorisation.

Ajouter les directives @check et @redact pour rechercher des données d'autorisation

Un cas d'utilisation courant de l'autorisation consiste à stocker des rôles d'autorisation personnalisés dans votre base de données, par exemple dans un tableau d'autorisations spécial, et à utiliser ces rôles pour autoriser les mutations à créer, mettre à jour ou supprimer des données.

À l'aide de recherches de données d'autorisation, vous pouvez interroger des rôles en fonction d'un ID utilisateur et utiliser des expressions CEL pour déterminer si la mutation est autorisée. Par exemple, vous pouvez écrire une mutation UpdateMovieTitle qui permet à un client autorisé de modifier les titres de films.

Pour le reste de cette discussion, supposons que la base de données de l'application d'avis sur les films stocke un rôle d'autorisation dans une table 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!
}

Dans l'exemple d'implémentation suivant, la mutation UpdateMovieTitle inclut un champ query pour récupérer les données de MoviePermission, ainsi que les directives suivantes pour garantir que l'opération est sécurisée et robuste:

  • Directive @transaction pour s'assurer que toutes les requêtes et vérifications d'autorisation sont effectuées ou échouent de manière atomique.
  • La directive @redact permet d'omettre les résultats de la requête de la réponse. Cela signifie que notre vérification d'autorisation est effectuée sur le serveur Data Connect, mais que les données sensibles ne sont pas exposées au client.
  • Paire de directives @check pour évaluer la logique d'autorisation sur les résultats de requête, par exemple pour vérifier qu'un userID donné dispose d'un rôle approprié pour effectuer des modifications.

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

Antimodèles à éviter dans l'autorisation

La section précédente décrit les modèles à suivre lorsque vous utilisez la directive @auth.

Vous devez également connaître les antimodèles importants à éviter.

Éviter de transmettre des ID d'attributs utilisateur et des paramètres de jeton d'authentification dans les arguments de requête et de mutation

Firebase Authentication est un outil puissant pour présenter les flux d'authentification et capturer de manière sécurisée des données d'authentification telles que les ID utilisateur enregistrés et de nombreux champs stockés dans des jetons d'authentification.

Il est déconseillé de transmettre des ID utilisateur et des données de jeton d'authentification dans les arguments de requête et de mutation.

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

Évitez d'utiliser le niveau d'accès USER sans filtres.

Comme indiqué à plusieurs reprises dans le guide, les niveaux d'accès de base tels que USER, USER_ANON et USER_EMAIL_VERIFIED sont des références et des points de départ pour les vérifications d'autorisation, à améliorer avec des filtres et des expressions. L'utilisation de ces niveaux sans filtre ni expression correspondants qui vérifient quel utilisateur effectue la requête est essentiellement équivalente à l'utilisation du niveau PUBLIC.

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

Éviter d'utiliser le niveau d'accès PUBLIC ou USER pour le prototypage

Pour accélérer le développement, il peut être tentant de définir toutes les opérations au niveau d'accès PUBLIC ou USER sans améliorations supplémentaires pour autoriser toutes les opérations et vous permettre de tester rapidement votre code.

Une fois que vous avez effectué le prototypage initial de cette manière, commencez à passer de NO_ACCESS à une autorisation prête à la production avec les niveaux PUBLIC et USER. Toutefois, ne les déployez pas en tant que PUBLIC ou USER sans ajouter de logique supplémentaire, comme indiqué dans ce guide.

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

Utiliser Firebase App Check pour l'attestation d'application

L'authentification et l'autorisation sont des composants essentiels de la sécurité Data Connect. L'authentification et l'autorisation combinées à l'attestation d'application constituent une solution de sécurité très robuste.

Avec l'attestation via Firebase App Check, les appareils exécutant votre application utiliseront un fournisseur d'attestation d'application ou d'appareil qui atteste que les opérations Data Connect proviennent de votre application authentique et que les requêtes proviennent d'un appareil authentique et non falsifié. Cette attestation est jointe à chaque requête envoyée par votre application à Data Connect.

Pour savoir comment activer App Check pour Data Connect et inclure son SDK client dans votre application, consultez la présentation de App Check.

Niveaux d'authentification pour la directive @auth(level)

Le tableau suivant liste tous les niveaux d'accès standards et leurs équivalents CEL. Les niveaux d'authentification sont listés de manière croissante : chaque niveau englobe tous les utilisateurs correspondant aux niveaux suivants.

Niveau Définition
PUBLIC L'opération peut être exécutée par n'importe qui, avec ou sans authentification.

Considérations:Les données peuvent être lues ou modifiées par n'importe quel utilisateur. Firebase recommande ce niveau d'autorisation pour les données consultables publiquement, comme les fiches de produits ou de médias. Consultez les exemples de bonnes pratiques et alternatives.

Équivalent à @auth(expr: "true")

Les filtres et expressions @auth ne peuvent pas être utilisés avec ce niveau d'accès. Toutes ces expressions échoueront avec une erreur 400 "Bad Request".
USER_ANON Tout utilisateur identifié, y compris ceux qui se sont connectés de manière anonyme avec Firebase Authentication, est autorisé à effectuer la requête ou la mutation.

Remarque: USER_ANON est un sur-ensemble de USER.

Considérations:Notez que vous devez concevoir soigneusement vos requêtes et vos mutations pour ce niveau d'autorisation. Ce niveau permet à l'utilisateur d'être connecté anonymement (connexion automatique liée uniquement à un appareil utilisateur) avec Authentication, et n'effectue pas d'autres vérifications, par exemple pour déterminer si les données appartiennent à l'utilisateur. Consultez les exemples de bonnes pratiques et les alternatives.

Étant donné que les flux de connexion anonyme Authentication génèrent un uid, le niveau USER_ANON est équivalent à
@auth(expr: "auth.uid != nil")
USER Tout utilisateur qui s'est connecté avec Firebase Authentication est autorisé à effectuer la requête ou la mutation, à l'exception des utilisateurs anonymes.

Considérations:Notez que vous devez concevoir soigneusement vos requêtes et vos mutations pour ce niveau d'autorisation. Ce niveau vérifie uniquement que l'utilisateur est connecté avec Authentication et n'effectue pas d'autres vérifications, par exemple pour déterminer si les données appartiennent à l'utilisateur. Consultez les exemples de bonnes pratiques et d'alternatives.

Équivaut à @auth(expr: "auth.uid != nil && auth.token.firebase.sign_in_provider != 'anonymous'")"
USER_EMAIL_VERIFIED Tout utilisateur qui s'est connecté avec Firebase Authentication avec une adresse e-mail validée est autorisé à effectuer la requête ou la mutation.

Considérations:Étant donné que la validation de l'adresse e-mail est effectuée à l'aide de Authentication, elle repose sur une méthode Authentication plus robuste. Ce niveau offre donc une sécurité supplémentaire par rapport à USER ou USER_ANON. Ce niveau ne vérifie que l'utilisateur est connecté avec Authentication avec une adresse e-mail validée et n'effectue pas d'autres vérifications, par exemple pour déterminer si les données appartiennent à l'utilisateur. Consultez les exemples de bonnes pratiques et alternatives.

Équivaut à @auth(expr: "auth.uid != nil && auth.token.email_verified")"
NO_ACCESS Cette opération ne peut pas être exécutée en dehors d'un contexte de SDK Admin.

Équivaut à @auth(expr: "false")

Documentation de référence CEL pour @auth(expr) et @check(expr)

Comme indiqué dans d'autres exemples de ce guide, vous pouvez et devez utiliser des expressions définies en langage CEL (Common Expression Language) pour contrôler l'autorisation de Data Connect à l'aide des directives @auth(expr:) et @check.

Cette section présente la syntaxe CEL pertinente pour créer des expressions pour ces directives.

Vous trouverez des informations de référence complètes sur CEL dans la spécification CEL.

Variables de test transmises dans les requêtes et les mutations

La syntaxe @auth(expr) vous permet d'accéder aux variables à partir de requêtes et de mutations, et de les tester.

Par exemple, vous pouvez inclure une variable d'opération, telle que $status, à l'aide de vars.status.

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

Données disponibles pour les expressions

Les expressions CEL @auth(expr:) et @check(expr:) peuvent évaluer les éléments suivants:

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

De plus, les expressions @check(expr:) peuvent évaluer:

  • this (valeur du champ actuel)

Objet request.operationName

L'objet request.operarationName stocke le type d'opération, qu'il s'agisse d'une requête ou d'une mutation.

L'objet vars

L'objet vars permet à vos expressions d'accéder à toutes les variables transmises dans votre requête ou votre mutation.

Vous pouvez utiliser vars.<variablename> dans une expression comme alias du request.variables.<variablename> qualifié complet:

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

L'objet auth

Authentication identifie les utilisateurs qui demandent l'accès à vos données et fournit ces informations en tant qu'objet sur lequel vous pouvez vous appuyer dans vos expressions.

Dans vos filtres et expressions, vous pouvez utiliser auth comme alias pour request.auth.

L'objet d'authentification contient les informations suivantes:

  • uid: ID utilisateur unique attribué à l'utilisateur à l'origine de la requête.
  • token: carte des valeurs collectées par Authentication.

Pour en savoir plus sur le contenu de auth.token, consultez la section Données dans les jetons d'authentification.

Liaison this

La liaison this renvoie le champ auquel la directive @check est associée. Dans un cas de base, vous pouvez évaluer les résultats de requête à valeur unique.

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 le champ renvoyé apparaît plusieurs fois, car un ancêtre est une liste, chaque occurrence est testée avec this lié à chaque valeur.

Pour un chemin donné, si un ancêtre est null ou [], le champ ne sera pas atteint et l'évaluation CEL sera ignorée pour ce chemin. En d'autres termes, l'évaluation n'a lieu que lorsque this est null ou non null, mais jamais undefined.

Lorsque le champ lui-même est une liste ou un objet, this suit la même structure (y compris tous les descendants sélectionnés en cas d'objets), comme illustré dans l'exemple suivant.

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

Syntaxe des expressions complexes

Vous pouvez écrire des expressions plus complexes en les combinant avec les opérateurs && et ||.

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

La section suivante décrit tous les opérateurs disponibles.

Opérateurs et priorité des opérateurs

Utilisez le tableau suivant comme référence pour les opérateurs et leur priorité correspondante.

Étant donné des expressions arbitraires a et b, un champ f et un indice i.

Opérateur Description Associativité
a[i] a() a.f Index, appel, accès aux champs de gauche à droite
!a -a Négation unaire de droite à gauche
a/b a%b a*b Opérateurs multiplicatifs de gauche à droite
a+b a-b Opérateurs additifs de gauche à droite
a>b a>=b a<b a<=b Opérateurs relationnels de gauche à droite
a in b Existence dans une liste ou une carte de gauche à droite
type(a) == t Comparaison de types, où t peut être bool, int, float, nombre, chaîne, liste, mappage, code temporel ou durée de gauche à droite
a==b a!=b Opérateurs de comparaison de gauche à droite
a && b Opérateur AND conditionnel de gauche à droite
a || b OR conditionnel de gauche à droite
a ? true_value : false_value Expression ternaire de gauche à droite

Données dans les jetons d'authentification

L'objet auth.token peut contenir les valeurs suivantes:

Champ Description
email Adresse e-mail associée au compte, le cas échéant.
email_verified true si l'utilisateur a confirmé qu'il avait accès à l'adresse email. Certains fournisseurs valident automatiquement les adresses e-mail qu'ils possèdent.
phone_number Numéro de téléphone associé au compte, le cas échéant
name Nom à afficher de l'utilisateur, le cas échéant.
sub UID Firebase de l'utilisateur. Il doit être unique au sein d'un projet.
firebase.identities Dictionnaire de toutes les identités associées au compte de cet utilisateur. Les clés du dictionnaire peuvent être les suivantes: email, phone, google.com, facebook.com, github.com ou twitter.com. Les valeurs du dictionnaire sont des tableaux d'identifiants uniques pour chaque fournisseur d'identité associé au compte. Par exemple, auth.token.firebase.identities["google.com"][0] contient le premier ID utilisateur Google associé au compte.
firebase.sign_in_provider Fournisseur de connexion utilisé pour obtenir ce jeton. Peut être l'une des chaînes suivantes: custom, password, phone, anonymous, google.com, facebook.com, github.com ou twitter.com.
firebase.tenant TenantId associé au compte, le cas échéant. Par exemple : tenant2-m6tyz

Champs supplémentaires dans les jetons d'ID JWT

Vous pouvez également accéder aux champs auth.token suivants:

Revendications de jetons personnalisées
alg Algorithme "RS256"
iss Émetteur Adresse e-mail du compte de service de votre projet
sub Objet Adresse e-mail du compte de service de votre projet
aud Public visé "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Date/Heure d'émission Heure actuelle, en secondes depuis l'epoch UNIX
exp Date/Heure d'expiration Durée, en secondes depuis l'époque UNIX, au bout de laquelle le jeton expire. Cette valeur peut correspondre à un maximum de 3 600 secondes après l'heure iat.
Remarque : Cette valeur ne contrôle que l'heure d'expiration du jeton personnalisé lui-même. Cependant, une fois que l'utilisateur est connecté à l'aide de signInWithCustomToken(), il reste connecté à l'appareil jusqu'à ce que sa session soit invalide ou qu'il se déconnecte.
<claims> (facultatif) Revendications personnalisées facultatives à inclure dans le jeton, auxquelles vous pouvez accéder via auth.token (ou request.auth.token) dans les expressions. Par exemple, si vous créez une revendication personnalisée adminClaim, vous pouvez y accéder avec auth.token.adminClaim.

Étape suivante