Connetti Secure Data con autorizzazione e attestazione

Firebase Data Connect offre una solida sicurezza lato client con:

  • Autorizzazione dei client web e mobile
  • Controlli di autorizzazione individuali a livello di query e mutazione
  • Attestazione dell'app con Firebase App Check.

Data Connect estende questa sicurezza con:

  • Autorizzazione lato server
  • Sicurezza degli utenti del progetto Firebase e di Cloud SQL con IAM.

Autorizza le query e le mutazioni del client

Data Connect è completamente integrato con Firebase Authentication, pertanto puoi utilizzare nel tuo design dati completi sugli utenti che accedono ai tuoi dati (autenticazione) per stabilire quali dati possono essere accessibili a questi utenti (autorizzazione).

Data Connect fornisce una direttiva @auth per query e mutazioni che consente di impostare il livello di autenticazione richiesto per autorizzare l'operazione. Questa guida introduce la direttiva @auth con esempi.

Inoltre, Data Connect supporta l'esecuzione di query incorporate nelle mutazioni, in modo da poter recuperare criteri di autorizzazione aggiuntivi che hai archiviato nel database e utilizzarli nelle direttive @check per decidere se le mutazioni esterne sono autorizzate. Per questo caso di autorizzazione, la direttiva @redact consente di controllare se i risultati delle query vengono restituiti ai client nel protocollo di rete e se la query incorporata viene omessa negli SDK generati. Consulta la introduzione a queste direttive, con esempi.

Informazioni sulla direttiva @auth

Puoi parametrizzare la direttiva @auth in modo che segua uno di diversi livelli di accesso preimpostati che coprono molti scenari di accesso comuni. Questi livelli vanno da PUBLIC (che consente query e mutazioni da tutti i client senza autenticazione di alcun tipo) a NO_ACCESS (che non consente query e mutazioni al di fuori degli ambienti di server con privilegi che utilizzano l'SDK Admin di Firebase). Ciascuno di questi livelli è correlato ai flussi di autenticazione forniti da Firebase Authentication.

Livello Definizione
PUBLIC L'operazione può essere eseguita da chiunque con o senza autenticazione.
PUBLIC L'operazione può essere eseguita da chiunque con o senza autenticazione.
USER_ANON Qualsiasi utente identificato, inclusi quelli che hanno eseguito l'accesso in forma anonima con Firebase Authentication, è autorizzato a eseguire la query o la mutazione.
USER Qualsiasi utente che ha eseguito l'accesso con Firebase Authentication è autorizzato a eseguire la query o la mutazione, ad eccezione degli utenti che hanno eseguito l'accesso in forma anonima.
USER_EMAIL_VERIFIED Qualsiasi utente che ha eseguito l'accesso con Firebase Authentication con un indirizzo email verificato è autorizzato a eseguire la query o la mutazione.
NO_ACCESS Questa operazione non può essere eseguita al di fuori del contesto di un SDK Admin.

Utilizzando questi livelli di accesso preimpostati come punto di partenza, puoi definire controlli di autorizzazione complessi e robusti nella direttiva @auth utilizzando i filtri where e le espressioni CEL (Common Expression Language) valutate sul server.

Utilizza la direttiva @auth per implementare scenari di autorizzazione comuni

I livelli di accesso preimpostati sono il punto di partenza per l'autorizzazione.

Il livello di accesso USER è il livello di base più utile per iniziare.

L'accesso completamente sicuro si basa sul livello USER, oltre a filtri ed espressioni che controllano gli attributi utente, gli attributi delle risorse, i ruoli e altri controlli. I livelli USER_ANON e USER_EMAIL_VERIFIED sono varianti del caso USER.

La sintassi delle espressioni consente di valutare i dati utilizzando un oggetto auth che rappresenta i dati di autenticazione trasmessi con le operazioni, sia i dati standard nei token di autenticazione sia i dati personalizzati nei token. Per l'elenco dei campi disponibili nell'oggetto auth, consulta la sezione di riferimento.

Naturalmente, esistono casi d'uso in cui PUBLIC è il livello di accesso corretto per iniziare. Anche in questo caso, un livello di accesso è sempre un punto di partenza e sono necessari filtri ed espressioni aggiuntivi per una sicurezza solida.

Questa guida ora fornisce esempi di come eseguire l'implementazione su USER e PUBLIC.

Un esempio motivante

I seguenti esempi di best practice fanno riferimento allo schema seguente per una piattaforma di blogging con determinati contenuti protetti da un piano di pagamento.

Una piattaforma di questo tipo potrebbe modellare Users e 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")
}

Risorse di proprietà dell'utente

Firebase consiglia di scrivere filtri ed espressioni che testano la proprietà dell'utente di una risorsa, nei seguenti casi, la proprietà di Posts.

Negli esempi seguenti, i dati dei token di autenticazione vengono letti e confrontati utilizzando le espressioni. Il pattern tipico è utilizzare espressioni come where: {authorUid: {eq_expr: "auth.uid"}} per confrontare un authorUid archiviato con il auth.uid (ID utente) passato nel token di autenticazione.

Crea

Questa prassi di autorizzazione inizia aggiungendo il auth.uid del token di autenticazione a ogni nuovo Post come campo authorUid per consentire il confronto nei test di autorizzazione successivi.

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

Quando un client tenta di aggiornare un Post, puoi testare il auth.uid passato rispetto al authorUid archiviato.

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

La stessa tecnica viene utilizzata per autorizzare le operazioni di eliminazione.

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

Filtraggio dei dati

Il sistema di autorizzazione di Data Connect ti consente di scrivere filtri sofisticati combinati con livelli di accesso preimpostati come PUBLIC, nonché di utilizzare i dati dei token di autenticazione.

Il sistema di autorizzazione ti consente anche di utilizzare solo espressioni, senza un livello di accesso di base, come mostrato in alcuni degli esempi riportati di seguito.

Filtra per attributi della risorsa

In questo caso, l'autorizzazione non si basa sui token di autenticazione poiché il livello di sicurezza di base è impostato su PUBLIC. Tuttavia, possiamo impostare esplicitamente i record nel nostro database come adatti all'accesso pubblico. Supponiamo di avere Post record nel nostro database con visibility impostato su "pubblico".

# 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
  }
}
Filtra per rivendicazioni utente

Supponiamo che tu abbia configurato rivendicazioni utente personalizzate che trasmettono token di autenticazione per identificare gli utenti in un piano "pro" per la tua app, contrassegnati con un campo auth.token.plan nel token di autenticazione. Le espressioni possono essere testate in base a questo 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
  }
}
Filtra per ordine + limite

In alternativa, potresti aver impostato visibility nei record Post per identificare i contenuti disponibili per gli utenti "Pro", ma per una visualizzazione di anteprima o teaser dei dati, limitare ulteriormente il numero di record restituiti.

# 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
  }
}
Filtra per ruolo

Se la tua rivendicazione personalizzata definisce un ruolo admin, puoi testare e autorizzare le operazioni di conseguenza.

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

Informazioni sulle direttive @check e @redact

L'istruzione @check verifica che i campi specificati siano presenti nei risultati della query. Un'espressione Common Expression Language (CEL) viene utilizzata per testare i valori del campo. Il comportamento predefinito dell'istruzione è controllare e rifiutare i nodi con valore null.

La direttiva @redact oscura una parte della risposta del client. I campi oscurati vengono comunque valutati per gli effetti collaterali (incluse le modifiche ai dati e @check) e i risultati sono comunque disponibili per i passaggi successivi nelle espressioni CEL.

In Data Connect, le direttive @check e @redact vengono utilizzate più spesso nel contesto dei controlli di autorizzazione. Consulta la discussione sulla ricerca dei dati di autorizzazione.

Aggiungi le direttive @check e @redact per cercare i dati di autorizzazione

Un caso d'uso comune per l'autorizzazione prevede la memorizzazione di ruoli di autorizzazione personalizzati nel database, ad esempio in una tabella delle autorizzazioni speciali, e l'utilizzo di questi ruoli per autorizzare le mutazioni per creare, aggiornare o eliminare i dati.

Utilizzando le ricerche dei dati di autorizzazione, puoi eseguire query sui ruoli in base a un ID utente e utilizzare le espressioni CEL per decidere se la mutazione è autorizzata. Ad esempio, potresti voler scrivere una mutazione UpdateMovieTitle che consenta a un cliente autorizzato di aggiornare i titoli dei film.

Per il resto di questa discussione, ipotizziamo che il database dell'app di recensioni di film memorizzi un ruolo di autorizzazione in una tabella 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!
}

Nell'esempio di implementazione seguente, la mutazione UpdateMovieTitle include un campo query per recuperare i dati da MoviePermission e le seguenti direttive per garantire che l'operazione sia sicura e affidabile:

  • Una direttiva @transaction per garantire che tutte le query e i controlli di autorizzazione vengano completati o non superati in modo atomico.
  • La direttiva @redact per omettere i risultati della query dalla risposta, il che significa che il nostro controllo di autorizzazione viene eseguito sul server Data Connect, ma i dati sensibili non vengono esposti al client.
  • Una coppia di direttive @check per valutare la logica di autorizzazione sui risultati delle query, ad esempio per verificare che un determinato userID abbia un ruolo appropriato per apportare modifiche.

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

Antipattern da evitare nell'autorizzazione

La sezione precedente illustra gli schemi da seguire quando si utilizza l'istruzione @auth.

Inoltre, devi conoscere gli antipattern importanti da evitare.

Evita di passare gli ID degli attributi utente e i parametri del token di autenticazione negli argomenti di query e mutazione

Firebase Authentication è uno strumento potente per presentare i flussi di autenticazione e acquisire in modo sicuro i dati di autenticazione, come gli ID utente registrati e numerosi campi memorizzati nei token di autenticazione.

Non è consigliabile passare gli ID utente e i dati dei token di autenticazione negli argomenti query e di mutazione.

# 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 di utilizzare il livello di accesso USER senza filtri

Come discusso più volte nella guida, i livelli di accesso di base come USER, USER_ANON, USER_EMAIL_VERIFIED sono linee di base e punti di partenza per i controlli di autorizzazione, da migliorare con filtri ed espressioni. L'utilizzo di questi livelli senza un filtro o un'espressione corrispondente che controlla chi sta eseguendo la richiesta è essenzialmente equivalente all'utilizzo del livello PUBLIC.

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

Evita di utilizzare il livello di accesso PUBLIC o USER per la prototipazione

Per velocizzare lo sviluppo, può essere allettante impostare tutte le operazioni sul livello di accesso PUBLIC o USER senza ulteriori miglioramenti per autorizzare tutte le operazioni e consentirti di testare rapidamente il codice.

Dopo aver creato una prototipazione iniziale in questo modo, inizia a passare dall'autorizzazione NO_ACCESS a quella pronta per la produzione con i livelli PUBLIC e USER. Tuttavia, non eseguirne il deployment come PUBLIC o USER senza aggiungere ulteriore logica come mostrato in questa guida.

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

Utilizzare Firebase App Check per l'attestazione delle app

L'autenticazione e l'autorizzazione sono componenti fondamentali della sicurezzaData Connect. L'autenticazione e l'autorizzazione combinate con la verifica dell'app costituiscono una soluzione di sicurezza molto solida.

Con l'attestazione tramite Firebase App Check, i dispositivi su cui è in esecuzione la tua app utilizzeranno un fornitore di attestazione dell'app o del dispositivo che attesta che le operazioni di Data Connect provengono dalla tua app autentica e le richieste provengono da un dispositivo autentico e non manomesso. Questa attestazione viene associata a ogni richiesta inviata dalla tua app a Data Connect.

Per scoprire come attivare App Check per Data Connect e includere il relativo SDK client nella tua app, consulta la panoramica di App Check.

Livelli di autenticazione per la direttiva @auth(level)

La tabella seguente elenca tutti i livelli di accesso standard e i relativi equivalenti CEL. I livelli di autenticazione sono elencati dal più ampio al più ristretto: ogni livello include tutti gli utenti che corrispondono ai livelli successivi.

Livello Definizione
PUBLIC L'operazione può essere eseguita da chiunque con o senza autenticazione.

Considerazioni: i dati possono essere letti o modificati da qualsiasi utente. Firebase consiglia questo livello di autorizzazione per i dati consultabili pubblicamente, come le schede di prodotti o multimediali. Consulta gli esempi e le alternative delle best practice.

Equivalente a @auth(expr: "true")

I filtri e le espressioni @auth non possono essere utilizzati in combinazione con questo livello di accesso. Qualsiasi espressione di questo tipo non andrà a buon fine con un errore di richiesta sbagliata 400.
USER_ANON Qualsiasi utente identificato, inclusi quelli che hanno eseguito l'accesso in forma anonima con Firebase Authentication, è autorizzato a eseguire la query o la mutazione.

Nota: USER_ANON è un superinsieme di USER.

Considerazioni: tieni presente che devi progettare attentamente le query e le mutazioni per questo livello di autorizzazione. Questo livello consente all'utente di accedere in forma anonima (accesso automatico collegato solo al dispositivo dell'utente) con Authentication e non esegue autonomamente altri controlli, ad esempio per verificare se i dati appartengono all'utente. Consulta gli esempi e le alternative delle best practice.

Poiché i flussi di accesso anonimi Authentication emettono un uid, il livello USER_ANON è equivalente a
@auth(expr: "auth.uid != nil")
USER Qualsiasi utente che ha eseguito l'accesso con Firebase Authentication è autorizzato a eseguire la query o la mutazione, ad eccezione degli utenti che hanno eseguito l'accesso in forma anonima.

Considerazioni: tieni presente che devi progettare attentamente le query e le mutazioni per questo livello di autorizzazione. Questo livello controlla solo che l'utente abbia eseguito l'accesso con Authentication e non esegue autonomamente altri controlli, ad esempio se i dati appartengono all'utente. Consulta gli esempi e le alternative delle best practice.

Equivalente a @auth(expr: "auth.uid != nil && auth.token.firebase.sign_in_provider != 'anonymous'")"
USER_EMAIL_VERIFIED Qualsiasi utente che ha eseguito l'accesso con Firebase Authentication con un indirizzo email verificato è autorizzato a eseguire la query o la mutazione.

Considerazioni: poiché la verifica email viene eseguita utilizzando Authentication, si basa su un metodo Authentication più affidabile, pertanto questo livello offre una maggiore sicurezza rispetto a USER o USER_ANON. Questo livello verifica solo che l'utente abbia eseguito l'accesso con Authentication utilizzando un indirizzo email verificato e non esegue autonomamente altri controlli, ad esempio per verificare se i dati appartengono all'utente. Consulta gli esempi e le alternative delle best practice.

Equivalente a @auth(expr: "auth.uid != nil && auth.token.email_verified")"
NO_ACCESS Questa operazione non può essere eseguita al di fuori del contesto di un SDK Admin.

Equivalente a @auth(expr: "false")

Riferimento CEL per @auth(expr) e @check(expr)

Come mostrato negli esempi in altre parti di questa guida, puoi e devi utilizzare le espressioni definite in Common Expression Language (CEL) per controllare l'autorizzazione per Data Connect utilizzando le direttive @auth(expr:) e @check.

Questa sezione illustra la sintassi CEL pertinente per la creazione di espressioni per queste direttive.

Le informazioni di riferimento complete per CEL sono riportate nella specifica CEL.

Prova le variabili passate in query e mutazioni

La sintassi @auth(expr) ti consente di accedere e testare le variabili da query e mutazione.

Ad esempio, puoi includere una variabile di operazione, come $status, utilizzando vars.status.

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

Dati disponibili per le espressioni

Sia le espressioni CEL @auth(expr:) che @check(expr:) possono valutare quanto segue:

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

Inoltre, le espressioni @check(expr:) possono valutare:

  • this (il valore del campo corrente)

L'oggetto request.operationName

L'oggetto request.operarationName memorizza il tipo di operazione, query o mutazione.

Oggetto vars

L'oggetto vars consente alle espressioni di accedere a tutte le variabili passate nella query o nella mutazione.

Puoi utilizzare vars.<variablename> in un'espressione come alias per il valore request.variables.<variablename> completamente qualificato:

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

Oggetto auth

Authentication identifica gli utenti che richiedono l'accesso ai tuoi dati e fornisce queste informazioni come oggetto su cui puoi basare le tue espressioni.

Nei filtri e nelle espressioni, puoi utilizzare auth come alias per request.auth.

L'oggetto auth contiene le seguenti informazioni:

  • uid: un ID utente univoco assegnato all'utente che effettua la richiesta.
  • token: una mappa dei valori raccolti da Authentication.

Per maggiori dettagli sul contenuto di auth.token, consulta Dati nei token di autenticazione

L'associazione this

L'associazione this restituisce il campo a cui è associata l'istruzione @check. In un caso di base, potresti valutare risultati della query a valore singolo.

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

Se il campo restituito si verifica più volte perché un qualsiasi antenato è un elenco, ogni occorrenza viene testata con this associato a ciascun valore.

Per un determinato percorso, se un antenato è null o [], il campo non verrà raggiunto e la valutazione CEL verrà saltata per quel percorso. In altre parole, la valutazione avviene solo quando this è null o non null, ma mai undefined.

Quando il campo stesso è un elenco o un oggetto, this segue la stessa struttura (inclusi tutti i discendenti selezionati in caso di oggetti), come illustrato nell' esempio seguente.

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

Sintassi delle espressioni complesse

Puoi scrivere espressioni più complesse combinandole con gli operatori && e ||.

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

La sezione seguente descrive tutti gli operatori disponibili.

Operatori e precedenza degli operatori

Utilizza la seguente tabella come riferimento per gli operatori e la relativa precedenza.

Dati espressioni arbitrarie a e b, un campo f e un indice i.

Operatore Descrizione Associatività
a[i] a() a.f Accesso a indici, chiamate e campi da sinistra a destra
!a -a Negazione unaria da destra a sinistra
a/b a%b a*b Operatori moltiplicativi da sinistra a destra
a+b a-b Operatori additivi da sinistra a destra
a>b a>=b a<b a<=b Operatori relazionali da sinistra a destra
a in b Presenza in un elenco o in una mappa da sinistra a destra
type(a) == t Confronto di tipo, dove t può essere bool, int, float, number, string, list, map, timestamp o duration da sinistra a destra
a==b a!=b Operatori di confronto da sinistra a destra
a && b E condizionale da sinistra a destra
a || b OR condizionale da sinistra a destra
a ? true_value : false_value Espressione ternaria da sinistra a destra

Dati nei token di autenticazione

L'oggetto auth.token può contenere i seguenti valori:

Campo Descrizione
email L'indirizzo email associato all'account, se presente.
email_verified true se l'utente ha verificato di avere accesso all'indirizzo email. Alcuni provider verificano automaticamente gli indirizzi email di loro proprietà.
phone_number Il numero di telefono associato all'account, se presente.
name Il nome visualizzato dell'utente, se impostato.
sub L'UID Firebase dell'utente. Deve essere univoco all'interno di un progetto.
firebase.identities Dizionario di tutte le identità associate all'account di questo utente. Le chiavi del dizionario possono essere una delle seguenti: email, phone, google.com, facebook.com, github.com, twitter.com. I valori del dizionario sono array di identificatori univoci per ogni provider di identità associato all'account. Ad esempio, auth.token.firebase.identities["google.com"][0] contiene il primo ID utente Google associato all'account.
firebase.sign_in_provider Il provider di accesso utilizzato per ottenere questo token. Può essere una delle seguenti stringhe: custom, password, phone, anonymous, google.com, facebook.com, github.com, twitter.com.
firebase.tenant Il tenantId associato all'account, se presente. Ad esempio, tenant2-m6tyz

Campi aggiuntivi nei token ID JWT

Puoi anche accedere ai seguenti campi auth.token:

Richieste di token personalizzati
alg Algoritmo "RS256"
iss Emittente L'indirizzo email dell'account di servizio del progetto
sub Oggetto L'indirizzo email dell'account di servizio del progetto
aud Pubblico "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Data/ora di emissione L'ora corrente, in secondi dall'epoca UNIX
exp Scadenza La data e l'ora in cui scade il token, espressa in secondi dall'epoca UNIX. Deve essere al massimo 3600 secondi dopo il valore iat.
Nota: questo controlla solo la data di scadenza del token personalizzato stesso. Tuttavia, una volta che un utente ha eseguito l'accesso utilizzando signInWithCustomToken(), l'accesso al dispositivo rimarrà attivo finché la sessione non viene invalidata o l'utente non si disconnette.
<claims> (facoltativo) Dichiarazioni personalizzate facoltative da includere nel token, a cui è possibile accedere tramite auth.token (o request.auth.token) nelle espressioni. Ad esempio, se crei un reclamo personalizzato adminClaim, puoi accedervi con auth.token.adminClaim.

Quali sono i passaggi successivi?