Gli SDK Admin di Firebase Data Connect consentono di chiamare query e mutazioni da ambienti attendibili come Cloud Functions, backend personalizzati o la tua workstation. Analogamente alla generazione di SDK per le app client, puoi generare un SDK Admin personalizzato in parallelo alla progettazione di schemi, query e mutazioni di cui esegui il deployment nel servizio Data Connect. Dopodiché, puoi integrare i metodi di questo SDK nella logica di backend o negli script di amministrazione.
Come abbiamo già detto, è importante notare che le Data Connect query e le mutazioni non vengono inviate dai client al momento della richiesta. Quando viene eseguito il deployment, le operazioni Data Connect vengono archiviate sul server, come Cloud Functions. Ciò significa che ogni volta che esegui il deployment delle modifiche alle query e alle mutazioni, devi anche rigenerare gli SDK Admin ed eseguire di nuovo il deployment di tutti i servizi che li utilizzano.
Prima di iniziare
- Scopri di più sulla progettazione di schemi, query e mutazioni Data Connect. In un flusso di lavoro tipico, li sviluppi in parallelo al codice dell'applicazione, inclusi tutti i servizi che utilizzano gli SDK Admin.
- Installa l'interfaccia a riga di comando di Firebase.
- Includi l'SDK Admin per Node.js come dipendenza ovunque prevedi di chiamare gli SDK Admin generati.
Generare gli SDK Admin
Dopo aver creato gli schemi, le query e le mutazioni di Data Connect, puoi generare un SDK Admin corrispondente:
Apri o crea un file
connector.yamle aggiungi una definizioneadminNodeSdk:connectorId: default generate: adminNodeSdk: outputDir: ../../dataconnect-generated/admin-generated package: "@dataconnect/admin-generated" packageJsonDir: ../..Il file
connector.yamlsi trova in genere nella stessa directory dei file GraphQL (.gql) che contengono le definizioni di query e mutazioni. Se hai già generato gli SDK client, questo file è già stato creato.Genera l'SDK.
Se hai installato l'estensione Data Connect di VS Code, gli SDK generati saranno sempre aggiornati.
In caso contrario, utilizza l'interfaccia a riga di comando di Firebase:
firebase dataconnect:sdk:generateIn alternativa, per rigenerare automaticamente gli SDK quando aggiorni i file
gql:firebase dataconnect:sdk:generate --watch
Eseguire operazioni da un SDK Admin
L'SDK Admin generato contiene interfacce e funzioni che corrispondono alle definizioni gql, che puoi utilizzare per eseguire operazioni sul database. Ad esempio, supponiamo di aver generato un SDK per un database di brani, insieme a una query, getSongs:
import { initializeApp } from "firebase-admin/app";
import { getSongs } from "@dataconnect/admin-generated";
const adminApp = initializeApp();
const songs = await getSongs(
{ limit: 4 },
{ impersonate: { unauthenticated: true } }
);
In alternativa, per specificare una configurazione del connettore:
import { initializeApp } from "firebase-admin/app";
import { getDataConnect } from "firebase-admin/data-connect";
import {
connectorConfig,
getSongs,
} from "@dataconnect/admin-generated";
const adminApp = initializeApp();
const adminDc = getDataConnect(connectorConfig);
const songs = await getSongs(
adminDc,
{ limit: 4 },
{ impersonate: { unauthenticated: true } }
);
Impersonare un utente non autenticato
Gli SDK Admin sono progettati per essere eseguiti da ambienti attendibili e pertanto hanno accesso illimitato ai database.
Quando esegui operazioni pubbliche con l'SDK Admin, devi evitare di eseguirle con privilegi di amministratore completi (seguendo il principio del privilegio minimo). Devi invece eseguire l'operazione come utente impersonato (vedi la sezione successiva) o come utente non autenticato impersonato.
Gli utenti non autenticati possono eseguire solo le operazioni contrassegnate come PUBLIC.
Nell'esempio precedente, la query getSongs viene eseguita come utente non autenticato.
Impersonare un utente
Puoi anche eseguire operazioni per conto di utenti specifici passando una parte o
la totalità di un Firebase Authentication token nell'opzione impersonate. Come minimo, tu
devi specificare l'ID utente dell'utente nella rivendicazione secondaria. (Questo è lo stesso valore del
auth.uid valore del server
a cui puoi fare riferimento nelle operazioni GraphQL Data Connect.)
Quando impersoni un utente, l'operazione avrà esito positivo solo se i dati utente forniti superano i controlli di autenticazione specificati nella definizione GraphQL.
Se chiami l'SDK generato da un endpoint accessibile pubblicamente, è fondamentale che l'endpoint richieda l'autenticazione e che tu convalidi l'integrità del token di autenticazione prima di utilizzarlo per simulare l'identità di un utente.
Quando utilizzi chiamabili Cloud Functions, il token di autenticazione viene verificato automaticamente e puoi utilizzarlo come nell'esempio seguente:
import { HttpsError, onCall } from "firebase-functions/https";
export const callableExample = onCall(async (req) => {
const authClaims = req.auth?.token;
if (!authClaims) {
throw new HttpsError("unauthenticated", "Unauthorized");
}
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
// ...
});
In caso contrario, utilizza il Admin SDK's verifyIdToken method per convalidare e decodificare
il token di autenticazione. Ad esempio, supponiamo che l'endpoint sia implementato come una
semplice funzione HTTP e che tu abbia passato il Firebase Authentication token
all'endpoint utilizzando l'intestazione authorization, come di consueto:
import { getAuth } from "firebase-admin/auth";
import { onRequest } from "firebase-functions/https";
const auth = getAuth();
export const httpExample = onRequest(async (req, res) => {
const token = req.header("authorization")?.replace(/^bearer\s+/i, "");
if (!token) {
res.sendStatus(401);
return;
}
let authClaims;
try {
authClaims = await auth.verifyIdToken(token);
} catch {
res.sendStatus(401);
return;
}
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
// ...
});
Solo quando esegui attività amministrative vere e proprie, come la migrazione dei dati, da un ambiente sicuro e non accessibile pubblicamente, devi specificare un ID utente che non proviene da una fonte verificabile:
// Never do this if end users can initiate execution of the code!
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
Eseguire con accesso illimitato
Se stai eseguendo un'operazione che richiede autorizzazioni a livello di amministratore, ometti il parametro impersonate dalla chiamata:
await upsertSong(adminDc, {
title: songTitle_one,
instrumentsUsed: [Instrument.VOCAL],
});
Un'operazione chiamata in questo modo ha accesso completo al database. Se hai query o mutazioni destinate solo a essere utilizzate per scopi amministrativi, devi definirle con la direttiva @auth(level: NO_ACCESS). In questo modo, solo i chiamanti a livello di amministratore possono eseguire queste operazioni.