Identity Platform-Mandanten programmatisch verwalten

In diesem Dokument wird erläutert, wie Sie die Identity Platform Admin SDK verwenden können, um Mandanten und ihre Nutzer programmatisch zu verwalten. Als Administrator können Sie unter anderem folgende Aktivitäten ausführen:

  • Nutzerverwaltung: Nutzer für einen bestimmten Mandanten erstellen, aktualisieren, löschen und auflisten.

  • Identitätsprüfung: Nutzer einer Anwendung identifizieren, um den Zugriff auf Ressourcen auf Ihrem eigenen Server einzuschränken.

  • Nutzer importieren: Nutzer aus einem externen Authentifizierungssystem oder einem anderen Identity Platform-Projekt bzw. -Mandanten migrieren.

  • Zugriffssteuerung mit benutzerdefinierten Anforderungen: Benutzerdefinierte Attribute für Nutzerkonten für einen bestimmten Mandanten definieren und verschiedene Zugriffssteuerungsstrategien wie die rollenbasierte Zugriffssteuerung implementieren.

  • Verwaltung der Nutzersitzung: Aktualisierungstokens eines Nutzers für einen bestimmten Mandanten widerrufen.

  • E-Mail-Aktionslinks: Benutzerdefinierte E-Mail-Links zum Zurücksetzen des Passworts, E-Mail-Links für die Anmeldung und E-Mail-Bestätigung für Nutzer eines bestimmten Mandanten generieren.

  • Mandantenverwaltung: Mandanten für ein bestimmtes Identity Platform-Projekt erstellen, auflisten, abrufen, aktualisieren und löschen.

  • OIDC- und SAML-Anbieter für Mandanten verwalten: OIDC- und SAML-Konfigurationen für einen bestimmten Mandanten programmatisch verwalten.

Hinweise

Unterstützte Features

In der folgenden Tabelle sind die von jedem SDK unterstützten Features in einer mandantenfähigen Umgebung aufgeführt:

Feature Node.js Java Python Einfach loslegen (Go) C#
Benutzerdefinierte Tokenerstellung
ID-Tokens verifizieren
Nutzer verwalten
Zugriff mit benutzerdefinierten Anforderungen steuern
Aktualisierungstokens widerrufen
Nutzer importieren
E-Mail-Aktionslinks generieren
Multi-Faktor-Authentifizierung
SAML-/OIDC-Anbieterkonfigurationen verwalten
Sitzungscookie verwalten

Die folgende Tabelle zeigt, welche Anmeldemethoden Sie mit dem Admin SDK und der Google Cloud Console in einem mandantenspezifischen Kontext konfigurieren können:

Funktion Google Cloud Console Admin SDK
E-Mail
OIDC
SAML
Soziale Netzwerke
Telefon
Multi-Faktor-Authentifizierung
Anonym

Mandantenverwaltung

Mit dem Admin SDK können Sie Mandanten programmatisch über eine sichere Serverumgebung verwalten, anstatt die Google Cloud Console zu verwenden. Dazu gehört die Möglichkeit, Mandanten zu erstellen, aufzulisten, abzurufen, zu ändern oder zu löschen.

Jeder Mandant enthält seine eigenen Identitätsanbieter, Einstellungen und Gruppen von Nutzern. Vorgänge zur Verwaltung der Mandantenkonfiguration (CRUD) sind über die übergeordnete Projektinstanz unter Verwendung von admin.auth().tenantManager() verfügbar.

Eine Mandantenkonfiguration stellt Informationen über einen Mandanten bereit, wie den Anzeigenamen, die Mandanten-ID und die Konfiguration der E-Mail-Authentifizierung.

Alle anderen Einstellungen eines Mandanten, z. B. Domains auf der weißen Liste und authentifizierte Weiterleitungs-URIs, werden vom übergeordneten Projekt übernommen. Diese müssen über die Google Cloud Console verwaltet werden.

Für Vorgänge wie die mandantenspezifische Nutzerverwaltung, das Konfigurieren von OIDC/SAML-Anbietern und das Generieren von E-Mail-Links benötigen Sie eine TenantAwareAuth-Instanz für den Zielmandanten (identifiziert durch ihre eindeutige tenantId).

Node.js

const tenantManager = admin.auth().tenantManager();
const tenantAuth = tenantManager.authForTenant(tenantId);

Python

from firebase_admin import tenant_mgt

tenant_client = tenant_mgt.auth_for_tenant(tenant_id)

Java

FirebaseAuth auth = FirebaseAuth.getInstance();
TenantManager tenantManager = auth.getTenantManager();
TenantAwareFirebaseAuth tenantAuth = tenantManager.getAuthForTenant(tenantId);

Alle Aufrufe an die User Management APIs, OIDC/SAML Provider Management APIs und Email Link Generation APIs sind im Bereich dieses Mandanten (anhand der TenantAwareAuth-Instanz).

Vorhandenen Mandanten abrufen

Das Admin SDK stellt die Methode getTenant() bereit, die Informationen zu einem Mandanten anhand seiner tenantId (eine eindeutige ID für den Mandanten) abruft.

Node.js

admin.auth().tenantManager().getTenant(tenantId)
  .then((tenant) => {
    console.log(tenant.toJSON());
  })
  .catch((error) => {
    // Handle error.
  });

Python

tenant = tenant_mgt.get_tenant(tenant_id)

print('Retreieved tenant:', tenant.tenant_id)

Java

Tenant tenant = FirebaseAuth.getInstance().getTenantManager().getTenant(tenantId);
System.out.println("Retrieved tenant: " + tenant.getTenantId());

Diese Methode gibt ein Tenant-Objekt zurück, das tenantId entspricht. Wenn die angegebene tenantId nicht zu einem vorhandenen Mandanten gehört, wird die zurückgegebene Prüfung mit dem Fehler auth/tenant-not-found abgelehnt.

Achten Sie darauf, eine Tenant-Instanz nicht mit einem TenantAwareAuth-Objekt zu verwechseln. authInstance.tenantManager().authForTenant() gibt eine TenantAwareAuth-Instanz zurück, die BaseAuth erweitert. Die Klasse Auth erweitert auch BaseAuth. BaseAuth bietet APIs zum Verwalten von Nutzern und zum Konfigurieren von OIDC-/SAML-Anbietern in verschiedenen Kontexten. Bei Auth befindet sich der Kontext auf der übergeordneten Projektebene. Bei TenantAwareAuth befindet sich der Kontext auf der Mandantenebene (der Mandant wird durch die Mandanten-ID bestimmt). Die SeitegetTenant() Methode mit grundlegenden Mandanteninformationen wie Mandanten-ID, Anzeigenamen und E-Mail-Anbietereinstellungen aufgelöst. Wenn Sie jedoch APIs für diesen Mandanten aufrufen möchten, müssen SieauthForTenant(tenantFromGetTenant.tenantId) verwenden.

Mandanten erstellen

Verwenden Sie die Methode createTenant(), um eine neue Mandantenkonfiguration zu erstellen:

Node.js

admin.auth().tenantManager().createTenant({
  displayName: 'myTenant1',
  emailSignInConfig: {
    enabled: true,
    passwordRequired: false, // Email link sign-in enabled.
  },
  // TODO: Remove if you don't want to enable multi-factor authentication.
  multiFactorConfig: {
    state: 'ENABLED',
    factorIds: ['phone']
  },
  // TODO: Remove if you don't want to register test phone numbers for use
  // with multi-factor authentication.
  testPhoneNumbers: {
    '+16505551234': '145678',
    '+16505550000': '123456'
  },
})
.then((createdTenant) => {
  console.log(createdTenant.toJSON());
})
.catch((error) => {
  // Handle error.
});

Python

tenant = tenant_mgt.create_tenant(
    display_name='myTenant1',
    enable_email_link_sign_in=True,
    allow_password_sign_up=True)

print('Created tenant:', tenant.tenant_id)

Java

Tenant.CreateRequest request = new Tenant.CreateRequest()
    .setDisplayName("myTenant1")
    .setEmailLinkSignInEnabled(true)
    .setPasswordSignInAllowed(true);
Tenant tenant = FirebaseAuth.getInstance().getTenantManager().createTenant(request);
System.out.println("Created tenant: " + tenant.getTenantId());

Sie können eine beliebige Kombination dieser Attribute verwenden:

Attribut Typ Beschreibung
displayName

string
    
Der Anzeigename des Mandanten. Es müssen 4 bis 20 Zeichen sein, bestehend aus Buchstaben, Ziffern und Bindestrichen und mit einem Buchstaben beginnen.
emailSignInConfig

{
  enable: boolean,
  passwordRequired: boolean
}
    
Konfiguration des E-Mail-Anbieters für die Anmeldung. Dazu gehört, ob der E-Mail-Anbieter aktiviert ist und ob ein Passwort für die E-Mail-Anmeldung erforderlich ist. Wenn nicht erforderlich, kann sich eine E-Mail-Anmeldung mit einem Passwort oder einer E-Mail-Anmeldung anmelden.
multiFactorConfig

{
  state: 'DISABLED' | 'ENABLED',
  factorIds: string[]
}
    
Gibt an, ob für den Mandanten eine Multi-Faktor-Authentifizierung aktiviert ist und welche Faktortypen zulässig sind. Derzeit ist die einzige unterstützte Faktor-ID phone.
testPhoneNumbers

{
  string: string
}
  
Eine Zuordnung von Telefonnummern und zugehörigen Multi-Faktor-Authentifizierungscodes zu Testzwecken. Es sind maximal zehn Einträge zulässig. Wenn Sie alle Testnummern entfernen möchten, setzen Sie dieses Feld auf null.

Die Methode gibt ein Tenant-Objekt für den neu erstellten Mandanten zurück.

Mandanten aktualisieren

Vorhandene Daten eines Mandanten können Sie mit der Methode updateTenant() ändern. Sie müssen den tenantId und die Attribute angeben, die für diesen Mandanten aktualisiert werden sollen.

Node.js

admin.auth().tenantManager().updateTenant(tenantId, {
  displayName: 'updatedName',
  emailSignInConfig: {
    enabled: false, // Disable email provider.
  },
  // Enable multi-factor authentication.
  multiFactorConfig: {
    state: 'ENABLED',
    factorIds: ['phone']
  },
  // Register phone numbers for testing.
  testPhoneNumbers: {
    '+16505551234': '145678',
    '+16505550000': '123456'
  },
})
.then((updatedTenant) => {
  console.log(updatedTenant.toJSON());
})
.catch((error) => {
  // Handle error.
});

Python

tenant = tenant_mgt.update_tenant(
    tenant_id,
    display_name='updatedName',
    allow_password_sign_up=False) # Disable email provider

print('Updated tenant:', tenant.tenant_id)

Java

Tenant.UpdateRequest request = new Tenant.UpdateRequest(tenantId)
    .setDisplayName("updatedName")
    .setPasswordSignInAllowed(false);
Tenant tenant = FirebaseAuth.getInstance().getTenantManager().updateTenant(request);
System.out.println("Updated tenant: " + tenant.getTenantId());

updateTenant() akzeptiert dieselben Attribute wie createTenant(). Alle Attribute sind optional. Wenn ein Attribut nicht angegeben wird, wird der vorhandene Wert nicht geändert.

Die Methode gibt nach Abschluss ein aktualisiertes Tenant-Objekt zurück. Wenn die angegebene tenantId nicht zu einem vorhandenen Mandanten gehört, wird das zurückgegebene Versprechen mit dem Fehler auth/tenant-not-found abgelehnt.

Mandanten löschen

Sie können einen Mandanten anhand seiner tenantId löschen:

Node.js

admin.auth().tenantManager().deleteTenant(tenantId)
  .then(() => {
    // Tenant deleted.
  })
  .catch((error) => {
    // Handle error.
  });

Python

tenant_mgt.delete_tenant(tenant_id)

Java

FirebaseAuth.getInstance().getTenantManager().deleteTenant(tenantId);

Die Methode gibt ein leeres Ergebnis zurück, wenn der Löschvorgang erfolgreich abgeschlossen ist. Wenn die angegebene tenantId nicht zu einem vorhandenen Mandanten gehört, wird die zurückgegebene Prüfung mit dem Fehler auth/tenant-not-found abgelehnt.

Mandanten auflisten

Verwenden Sie die Methode listTenants(), um vorhandene Mandanten aufzulisten:

Node.js

function listAllTenants(nextPageToken) {
  return admin.auth().tenantManager().listTenants(100, nextPageToken)
    .then((result) => {
      result.tenants.forEach((tenant) => {
        console.log(tenant.toJSON());
      });
      if (result.pageToken) {
        return listAllTenants(result.pageToken);
      }
    });
}

listAllTenants();

Python

for tenant in tenant_mgt.list_tenants().iterate_all():
    print('Retrieved tenant:', tenant.tenant_id)

Java

ListTenantsPage page = FirebaseAuth.getInstance().getTenantManager().listTenants(null);
for (Tenant tenant : page.iterateAll()) {
  System.out.println("Retrieved tenant: " + tenant.getTenantId());
}

Jeder Satz von Ergebnissen enthält eine Liste der Mandanten sowie ein Token für die nächste Seite, um den nächsten Mandanten-Satz aufzulisten. Wenn alle Mandanten bereits aufgelistet sind, wird kein pageToken zurückgegeben.

Wenn kein Feld maxResults angegeben ist, liegt der Standardwert bei 1.000 Mandanten pro Batch. Dies ist auch die maximale Anzahl der Mandanten, die gleichzeitig aufgelistet werden können. Jeder Wert, der größer als der Höchstwert ist, löst einen Argumentfehler aus. Wenn kein pageToken angegeben ist, listet die Methode Mandanten von Beginn an auf.

SAML- und OIDC-Anbieter programmatisch verwalten

Das Admin SDK bietet APIs für die programmatische Verwaltung der Konfiguration von SAML 2.0- (Security Assertion Markup Language) und OIDC-Anbietern (OpenID Connect) in einer sicheren Serverumgebung.

Mit dem Admin SDK können Sie diese Anbieter für einen bestimmten Mandanten verwalten. Dies ist mit dem Verwalten von OIDC- und SAML-Anbietern auf Projektebene vergleichbar.

Um Anbieter für einen Mandanten zu verwalten, erstellen Sie zuerst eine TenantAwareAuth-Instanz:

Node.js

const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');

Python

tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')

Java

TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager()
    .getAuthForTenant("TENANT-ID");

Sie können dann übliche Vorgänge wie das Erstellen, Ändern oder Löschen von Anbietern für einen Mandanten ausführen.

Anbieter erstellen

Der folgende Code zeigt, wie ein SAML-Anbieter für einen Mandanten erstellt wird:

Node.js

const newConfig = {
  displayName: 'SAML provider name',
  enabled: true,
  providerId: 'saml.myProvider',
  idpEntityId: 'IDP_ENTITY_ID',
  ssoURL: 'https://example.com/saml/sso/1234/',
  x509Certificates: [
    '-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----',
    '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----'
  ],
  rpEntityId: 'RP_ENTITY_ID',
  // Using the default callback URL.
  callbackURL: 'https://project-id.firebaseapp.com/__/auth/handler'
};

tenantAuth.createProviderConfig(newConfig).then(() => {
  // Successful creation.
}).catch((error) => {
  // Handle error.
});

Python

saml = tenant_client.create_saml_provider_config(
    display_name='SAML provider name',
    enabled=True,
    provider_id='saml.myProvider',
    idp_entity_id='IDP_ENTITY_ID',
    sso_url='https://example.com/saml/sso/1234/',
    x509_certificates=[
        '-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----',
        '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----',
    ],
    rp_entity_id='P_ENTITY_ID',
    callback_url='https://project-id.firebaseapp.com/__/auth/handler')

print('Created new SAML provider:', saml.provider_id)

Java

SamlProviderConfig.CreateRequest request = new SamlProviderConfig.CreateRequest()
    .setDisplayName("SAML provider name")
    .setEnabled(true)
    .setProviderId("saml.myProvider")
    .setIdpEntityId("IDP_ENTITY_ID")
    .setSsoUrl("https://example.com/saml/sso/1234/")
    .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT1...\n-----END CERTIFICATE-----")
    .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----")
    .setRpEntityId("RP_ENTITY_ID")
    .setCallbackUrl("https://project-id.firebaseapp.com/__/auth/handler");
SamlProviderConfig saml = tenantAuth.createSamlProviderConfig(request);
System.out.println("Created new SAML provider: " + saml.getProviderId());

Anbieter ändern

Der folgende Code zeigt, wie ein Anbieter geändert wird:

Node.js

const updatedConfig = {
  x509Certificates: [
    '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----',
    '-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----',
  ],
};
tenantAuth.updateProviderConfig('saml.myProvider', updatedConfig).then(() => {
  // Successful update.
}).catch((error) => {
  // Handle error.
});

Python

saml = tenant_client.update_saml_provider_config(
    'saml.myProvider',
    x509_certificates=[
        '-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----',
        '-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----',
    ])

print('Updated SAML provider:', saml.provider_id)

Java

SamlProviderConfig.UpdateRequest request =
    new SamlProviderConfig.UpdateRequest("saml.myProvider")
      .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT2...\n-----END CERTIFICATE-----")
      .addX509Certificate("-----BEGIN CERTIFICATE-----\nCERT3...\n-----END CERTIFICATE-----");
SamlProviderConfig saml = tenantAuth.updateSamlProviderConfig(request);
System.out.println("Updated SAML provider: " + saml.getProviderId());

Anbieter abrufen

Der folgende Code zeigt, wie die Anbieterkonfiguration für einen bestimmten Mandanten anhand dessen Anbieter-ID abgerufen wird:

Node.js

tenantAuth.getProviderConfig('saml.myProvider').then((config) => {
  // Get display name and whether it is enabled.
  console.log(config.displayName, config.enabled);
}).catch((error) => {
  // Handle error. Common error is that config is not found.
});

Python

saml = tennat_client.get_saml_provider_config('saml.myProvider')
print(saml.display_name, saml.enabled)

Java

SamlProviderConfig saml = tenantAuth.getSamlProviderConfig("saml.myProvider");

// Get display name and whether it is enabled.
System.out.println(saml.getDisplayName() + " " + saml.isEnabled());

Anbieter auflisten

Der folgende Code zeigt, wie Anbieterkonfigurationen für einen bestimmten Mandanten aufgelistet werden:

Node.js

// Returns 10 SAML provider configs starting from the specified nextPageToken offset.
tenantAuth.listProviderConfigs({type: 'saml', maxResults: 10, pageToken: 'nextPageToken'}).then((results) => {
  results.providerConfigs.forEach((config) => {
    console.log(config.providerId);
  });
  // To list the next 10:
  // return tenantAuth.listProviderConfigs(
  //     {type: 'saml', maxResults: 10, pageToken: results.pageToken});
}).catch((error) => {
  // Handle error.
});

Python

for saml in tenant_client.list_saml_provider_configs('nextPageToken').iterate_all():
    print(saml.provider_id)

Java

ListProviderConfigsPage<SamlProviderConfig> page = tenantAuth.listSamlProviderConfigs(
    "nextPageToken");
for (SamlProviderConfig saml : page.iterateAll()) {
  System.out.println(saml.getProviderId());
}

Anbieter löschen

Der folgende Code zeigt, wie ein Anbieter gelöscht wird:

Node.js

tenantAuth.deleteProviderConfig('saml.myProvider').then(() => {
  // Successful deletion.
}).catch((error) => {
  // Handle error.
});

Python

tenant_client.delete_saml_provider_config('saml.myProvider')

Java

tenantAuth.deleteSamlProviderConfig("saml.myProvider");

OIDC-Anbieter werden ähnlich wie OIDC-Anbieter auf Projektebene verwaltet, außer sie können von der entsprechenden TenantAwareAuth-Instanz statt einer Auth auf Projektebene verwaltet werden.

Weitere Informationen finden Sie unter SAML- und OIDC-Anbieter programmatisch verwalten.

Mandantenspezifische Nutzer verwalten

Mit dem Admin SDK können Sie alle Nutzer für einen bestimmten Mandanten erstellen, abrufen, aktualisieren, löschen und auflisten.

Als Erstes benötigen Sie eine TenantAwareAuth-Instanz für den entsprechenden Mandanten:

Node.js

const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');

Python

tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')

Java

TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager()
    .getAuthForTenant("TENANT-ID");

Nutzer abrufen

Sie können einen mandantenspezifischen Nutzer mit einer uid-ID abrufen:

Node.js

tenantAuth.getUser(uid)
  .then((userRecord) => {
    // See the UserRecord reference documentation to learn more.
    console.log('Successfully fetched user data:', userRecord.toJSON());
    // Tenant ID will be reflected in userRecord.tenantId.
  })
  .catch((error) => {
    console.log('Error fetching user data:', error);
  });

Python

	# Get an auth.Client from tenant_mgt.auth_for_tenant()
    user = tenant_client.get_user(uid)
    print('Successfully fetched user data:', user.uid)

Java

// Get an auth client from the firebase.App
UserRecord user = tenantAuth.getUser(uid);
System.out.println("Successfully fetched user data: " + user.getDisplayName());

Sie können einen Nutzer auch anhand seiner E-Mail-Adresse identifizieren:

Node.js

tenantAuth.getUserByEmail(email)
  .then((userRecord) => {
    // See the UserRecord reference documentation to learn more.
    console.log('Successfully fetched user data:', userRecord.toJSON());
    // Tenant ID will be reflected in userRecord.tenantId.
  })
  .catch((error) => {
    console.log('Error fetching user data:', error);
  });

Python

user = tenant_client.get_user_by_email(email)
print('Successfully fetched user data:', user.uid)

Java

// Get an auth client from the firebase.App
UserRecord user = tenantAuth.getUserByEmail(email);
System.out.println("Successfully fetched user data: " + user.getDisplayName());

Nutzer erstellen

Mit der Methode createUser() können Sie neue Nutzer für einen bestimmten Mandanten erstellen. Beim Erstellen eines neuen Nutzers ist die Angabe einer uid optional. Wenn nicht angegeben, stellt Identity Platform eine eindeutige ID bereit.

Node.js

tenantAuth.createUser({
  email: 'user@example.com',
  emailVerified: false,
  phoneNumber: '+11234567890',
  password: 'secretPassword',
  displayName: 'John Doe',
  photoURL: 'http://www.example.com/12345678/photo.png',
  disabled: false
})
.then((userRecord) => {
  // See the UserRecord reference documentation to learn more.
  console.log('Successfully created new user:', userRecord.uid);
  // Tenant ID will be reflected in userRecord.tenantId.
})
.catch((error) => {
  console.log('Error creating new user:', error);
});

Python

user = tenant_client.create_user(
    email='user@example.com',
    email_verified=False,
    phone_number='+15555550100',
    password='secretPassword',
    display_name='John Doe',
    photo_url='http://www.example.com/12345678/photo.png',
    disabled=False)
print('Sucessfully created new user:', user.uid)

Java

UserRecord.CreateRequest request = new UserRecord.CreateRequest()
    .setEmail("user@example.com")
    .setEmailVerified(false)
    .setPhoneNumber("+15555550100")
    .setPassword("secretPassword")
    .setDisplayName("John Doe")
    .setPhotoUrl("http://www.example.com/12345678/photo.png")
    .setDisabled(false);
UserRecord user = tenantAuth.createUser(request);
System.out.println("Successfully created user: " + user.getDisplayName());

Nutzer ändern

Sie können vorhandene Nutzer ändern, indem Sie ihre uid für die Methode updateUser() angeben:

Node.js

tenantAuth.updateUser(uid, {
  email: 'modifiedUser@example.com',
  phoneNumber: '+11234567890',
  emailVerified: true,
  password: 'newPassword',
  displayName: 'Jane Doe',
  photoURL: 'http://www.example.com/12345678/photo.png',
  disabled: true
})
.then((userRecord) => {
  // See the UserRecord reference documentation to learn more.
  console.log('Successfully updated user', userRecord.toJSON());
})
.catch((error) => {
  console.log('Error updating user:', error);
});

Python

user = tenant_client.update_user(
    uid,
    email='user@example.com',
    phone_number='+15555550100',
    email_verified=True,
    password='newPassword',
    display_name='John Doe',
    photo_url='http://www.example.com/12345678/photo.png',
    disabled=True)
print('Sucessfully updated user:', user.uid)

Java

UserRecord.UpdateRequest request = new UserRecord.UpdateRequest(uid)
    .setEmail("user@example.com")
    .setEmailVerified(true)
    .setPhoneNumber("+15555550100")
    .setPassword("newPassword")
    .setDisplayName("John Doe")
    .setPhotoUrl("http://www.example.com/12345678/photo.png")
    .setDisabled(true);
UserRecord user = tenantAuth.updateUser(request);
System.out.println("Successfully updated user: " + user.getDisplayName());

Nutzer löschen

Das folgende Beispiel zeigt, wie Sie einen Nutzer anhand seiner uid löschen:

Node.js

tenantAuth.deleteUser(uid)
  .then(() => {
    console.log('Successfully deleted user');
  })
  .catch((error) => {
    console.log('Error deleting user:', error);
  });

Python

tenant_client.delete_user(uid)
print('Successfully deleted user')

Java

tenantAuth.deleteUser(uid);

System.out.println("Successfully deleted user: " + uid);

Nutzer auflisten

Zum Abrufen einer gesamten Liste von Nutzern für einen bestimmten Mandanten in Stapeln verwenden Sie die Methode listUsers(). Jeder Stapel enthält eine Liste von Nutzerdatensätzen sowie ein Token für die nächste Seite, falls weitere Nutzer verbleiben.

Node.js

function listAllUsers(nextPageToken) {
  // List batch of users, 1000 at a time.
  tenantAuth.listUsers(1000, nextPageToken)
    .then((listUsersResult) => {
      listUsersResult.users.forEach((userRecord) => {
        console.log('user', userRecord.toJSON());
        // Tenant ID will be reflected in userRecord.tenantId.
      });
      if (listUsersResult.pageToken) {
        // List next batch of users.
        listAllUsers(listUsersResult.pageToken);
      }
    })
    .catch((error) => {
      console.log('Error listing users:', error);
    });
}
// Start listing users from the beginning, 1000 at a time.
listAllUsers();

Python

	# Note, behind the scenes, the iterator will retrive 1000 users at a time through the API
    for user in tenant_client.list_users().iterate_all():
        print('User: ' + user.uid)

	# Iterating by pages of 1000 users at a time.
    page = tenant_client.list_users()
    while page:
        for user in page.users:
            print('User: ' + user.uid)
        # Get next batch of users.
        page = page.get_next_page()

Java

// Note, behind the scenes, the ListUsersPage retrieves 1000 Users at a time
// through the API
ListUsersPage  page = tenantAuth.listUsers(null);
for (ExportedUserRecord user : page.iterateAll()) {
  System.out.println("User: " + user.getUid());
}

// Iterating by pages 100 users at a time.
page = tenantAuth.listUsers(null, 100);
while (page != null) {
  for (ExportedUserRecord user : page.getValues()) {
    System.out.println("User: " + user.getUid());
  }

  page = page.getNextPage();
}

Weitere Informationen finden Sie in der Admin SDK-Dokumentation unter Nutzer verwalten.

Nutzer importieren

Sie können das Admin SDK verwenden, um Nutzer gesammelt in einen bestimmten Mandanten mit erhöhten Berechtigungen zu importieren. Dies bietet zahlreiche Vorteile, z. B. die Migration von Nutzern aus einem anderen Identity Platform-Produkt, aus einem anderen Mandanten oder aus einem externen Authentifizierungssystem mit einem anderen Hash-Algorithmus. Sie können auch Nutzer mit föderierten Anbietern (wie SAML und OIDC) und benutzerdefinierten Anforderungen direkt gesammelt importieren.

Rufen Sie zuerst eine TenantAwareAuth-Instanz für den entsprechenden Mandanten ab:

Node.js

const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');

Python

tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')

Java

TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager()
    .getAuthForTenant("TENANT-ID");

Mit einem bestimmten Hash-Algorithmus können Sie bis zu 1.000 Nutzer gleichzeitig importieren.

Node.js

tenantAuth.importUsers([{
  uid: 'uid1',
  email: 'user1@example.com',
  // Must be provided in a byte buffer.
  passwordHash: Buffer.from('password-hash-1'),
  // Must be provided in a byte buffer.
  passwordSalt: Buffer.from('salt1')
},
{
  uid: 'uid2',
  email: 'user2@example.com',
  // Must be provided in a byte buffer.
  passwordHash: Buffer.from('password-hash-2'),
  // Must be provided in a byte buffer.
  passwordSalt: Buffer.from('salt2')

}], {
  hash: {
    algorithm: 'HMAC_SHA256',
    // Must be provided in a byte buffer.
    key: Buffer.from('secret')
  }
})
.then((results) => {
  results.errors.forEach(function(indexedError) {
  console.log('Error importing user ' + indexedError.index);
  });
})
.catch((error) => {
  console.log('Error importing users:', error);
});

Python

users = [
    auth.ImportUserRecord(
        uid='uid1',
        email='user1@example.com',
        password_hash=b'password_hash_1',
        password_salt=b'salt1'
    ),
    auth.ImportUserRecord(
        uid='uid2',
        email='user2@example.com',
        password_hash=b'password_hash_2',
        password_salt=b'salt2'
    ),
]

hash_alg = auth.UserImportHash.hmac_sha256(key=b'secret')
try:
    result = tenant_client.import_users(users, hash_alg=hash_alg)
    for err in result.errors:
        print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
    print('Error importing users:', error)

Java

List<ImportUserRecord> users = new ArrayList<>();
users.add(ImportUserRecord.builder()
    .setUid("uid1")
    .setEmail("user1@example.com")
    .setPasswordHash("password-hash-1".getBytes())
    .setPasswordSalt("salt1".getBytes())
    .build());
users.add(ImportUserRecord.builder()
    .setUid("uid2")
    .setEmail("user2@example.com")
    .setPasswordHash("password-hash-2".getBytes())
    .setPasswordSalt("salt2".getBytes())
    .build());
UserImportHash hmacSha256 = HmacSha256.builder()
    .setKey("secret".getBytes())
    .build();
UserImportResult result = tenantAuth.importUsers(users, UserImportOptions.withHash(hmacSha256));

for (ErrorInfo error : result.getErrors()) {
  System.out.println("Failed to import user: " + error.getReason());
}

Für alle importierten Nutzer wird tenantId auf tenantAuth.tenantId festgelegt.

Nutzer ohne Passwörter können auch in einen bestimmten Mandanten importiert werden. Diese Nutzer können mit föderierten Anbietern und benutzerdefinierten Anforderungen importiert werden.

Node,js

tenantAuth.importUsers([{
  uid: 'some-uid',
  displayName: 'John Doe',
  email: 'johndoe@acme.com',
  photoURL: 'http://www.example.com/12345678/photo.png',
  emailVerified: true,
  phoneNumber: '+11234567890',
  // Set this user as admin.
  customClaims: {admin: true},
  // User with SAML provider.
  providerData: [{
    uid: 'saml-uid',
    email: 'johndoe@acme.com',
    displayName: 'John Doe',
    photoURL: 'http://www.example.com/12345678/photo.png',
    providerId: 'saml.acme'
  }]
}])
.then(function(results) {
  results.errors.forEach(function(indexedError) {
  console.log('Error importing user ' + indexedError.index);
  });
})
.catch(function(error) {
  console.log('Error importing users:', error);
});

Python

users = [
    auth.ImportUserRecord(
        uid='some-uid',
        display_name='John Doe',
        email='johndoe@gmail.com',
        photo_url='http://www.example.com/12345678/photo.png',
        email_verified=True,
        phone_number='+11234567890',
        custom_claims={'admin': True}, # set this user as admin
        provider_data=[ # user with SAML provider
            auth.UserProvider(
                uid='saml-uid',
                email='johndoe@gmail.com',
                display_name='John Doe',
                photo_url='http://www.example.com/12345678/photo.png',
                provider_id='saml.acme'
            )
        ],
    ),
]
try:
    result = tenant_client.import_users(users)
    for err in result.errors:
        print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
    print('Error importing users:', error)

Java

List<ImportUserRecord> users = new ArrayList<>();
users.add(ImportUserRecord.builder()
    .setUid("some-uid")
    .setDisplayName("John Doe")
    .setEmail("johndoe@acme.com")
    .setPhotoUrl("https://www.example.com/12345678/photo.png")
    .setEmailVerified(true)
    .setPhoneNumber("+11234567890")
    // Set this user as admin.
    .putCustomClaim("admin", true)
    // User with SAML provider.
    .addUserProvider(UserProvider.builder()
        .setUid("saml-uid")
        .setEmail("johndoe@acme.com")
        .setDisplayName("John Doe")
        .setPhotoUrl("https://www.example.com/12345678/photo.png")
        .setProviderId("saml.acme")
        .build())
    .build());

UserImportResult result = tenantAuth.importUsers(users);

for (ErrorInfo error : result.getErrors()) {
  System.out.println("Failed to import user: " + error.getReason());
}

Weitere Informationen finden Sie in der Admin SDK-Dokumentation unter Nutzer importieren.

Identitätsprüfung

Wenn eine Identity Platform-Clientanwendung mit einem benutzerdefinierten Back-End-Server kommuniziert, muss der aktuell angemeldete Nutzer auf diesem Server identifiziert werden. Dies kann sicher erfolgen, indem Sie das ID-Token des Nutzers senden, nachdem Sie sich über eine sichere Verbindung zu Ihrem Server angemeldet haben. Der Server kann dann die Integrität und Authentizität des ID-Tokens überprüfen.

Das Admin SDK hat eine integrierte Methode zum Prüfen und Decodieren von ID-Tokens für einen bestimmten Mandanten.

Nachdem der Nutzer erfolgreich über den Client bei einem bestimmten Mandanten angemeldet wurde, rufen Sie das ID-Token des Nutzers mithilfe des Client SDK ab:

auth.tenantId = 'TENANT-ID';
auth.signInWithEmailAndPassword('user@example.com', 'password')
  .then((userCredential) => {
    return userCredential.user.getIdToken();
  })
  .then((idToken) => {
    // Send the ID token to server for verification. ID token should be scoped to TENANT-ID.
  });

Erstellen Sie eine TenantAwareAuth-Instanz auf dem Server:

Node.js

const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');

Python

tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')

Java

TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager()
    .getAuthForTenant("TENANT-ID");

Sie können dann das ID-Token für diesen bestimmten Mandanten prüfen:

Node.js

// idToken comes from the client app
tenantAuth.verifyIdToken(idToken)
  .then((decodedToken) => {
    let uid = decodedToken.uid;
    // This should be set to TENANT-ID. Otherwise auth/mismatching-tenant-id error thrown.
    console.log(decodedToken.firebase.tenant);
    // ...
  }).catch((error) => {
    // Handle error
  });

Eine serverseitige Ressource kann von mehreren Mandanten mit unterschiedlichen Zugriffsebenen zugänglich sein. Da die Mandanten-ID in diesem Fall möglicherweise nicht im Voraus bekannt ist, kann das ID-Token zuerst auf Projektebene verifiziert werden.

admin.auth().verifyIdToken(idToken)
  .then((decodedToken) => {
    if (decodedToken.firebase.tenant === 'TENANT-ID1') {
      // Allow appropriate level of access for TENANT-ID1.
    } else if (decodedToken.firebase.tenant === 'TENANT-ID2') {
      // Allow appropriate level of access for TENANT-ID2.
    } else {
      // Block access for all other tenants.
      throw new Error('Access not allowed.');
    }
  }).catch((error) => {
    // Handle error
  });

Python

	# id_token comes from the client app
    try:
        decoded_token = tenant_client.verify_id_token(id_token)

        # This should be set to TENANT-ID. Otherwise TenantIdMismatchError error raised.
        print('Verified ID token from tenant:', decoded_token['firebase']['tenant'])
    except tenant_mgt.TenantIdMismatchError:
        # Token revoked, inform the user to reauthenticate or signOut().
        pass

Java

try {
  // idToken comes from the client app
  FirebaseToken token = tenantAuth.verifyIdToken(idToken);
  // TenantId on the FirebaseToken should be set to TENANT-ID.
  // Otherwise "tenant-id-mismatch" error thrown.
  System.out.println("Verified ID token from tenant: " + token.getTenantId());
} catch (FirebaseAuthException e) {
  System.out.println("error verifying ID token: " + e.getMessage());
}

Weitere Informationen finden Sie in der Dokumentation zum Thema ID-Tokens prüfen.

Nutzersitzungen verwalten

Identity Platform-Sitzungen sind langlebig. Bei jeder Anmeldung eines Nutzers werden die Anmeldedaten des Nutzers auf dem Identity Platform-Server überprüft und dann gegen ein kurzlebiges ID-Token und ein langlebiges Aktualisierungstoken ausgetauscht. ID-Tokens dauern eine Stunde. Aktualisierungstokens laufen nie ab, es sei denn, ein Nutzer ist deaktiviert, gelöscht oder wird von einer großen Kontoänderung wie eine E-Mail-Adresse oder ein Passwort-Update geändert.

In einigen Fällen muss das Aktualisierungstoken eines Nutzers aus Sicherheitsgründen widerrufen werden, z. B. wenn der Nutzer ein verlorenes oder gestohlenes Gerät meldet, eine allgemeine Sicherheitslücke in einer App oder ein erhebliches Datenleck in einem aktiven Token entdeckt. Das Admin SDK bietet eine API, mit der alle ausgegebenen Aktualisierungstokens für einen bestimmten Nutzer eines bestimmten Mandanten widerrufen werden.

Als Erstes benötigen Sie eine TenantAwareAuth-Instanz:

Node.js

const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');

Python

tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')

Java

TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager()
    .getAuthForTenant("TENANT-ID");

Die Aktualisierungstokens können dann durch Angabe der uid dieses Nutzers widerrufen werden:

Node.js

// Revoke all refresh tokens for a specified user in a specified tenant for whatever reason.
// Retrieve the timestamp of the revocation, in seconds since the epoch.
tenantAuth.revokeRefreshTokens(uid)
  .then(() => {
    return tenantAuth.getUser(uid);
  })
  .then((userRecord) => {
    return new Date(userRecord.tokensValidAfterTime).getTime() / 1000;
  })
  .then((timestamp) => {
    console.log('Tokens revoked at: ', timestamp);
  });

Python

	# Revoke all refresh tokens for a specified user in a specified tenant for whatever reason.
	# Retrieve the timestamp of the revocation, in seconds since the epoch.
    tenant_client.revoke_refresh_tokens(uid)

    user = tenant_client.get_user(uid)
    # Convert to seconds as the auth_time in the token claims is in seconds.
    revocation_second = user.tokens_valid_after_timestamp / 1000
    print('Tokens revoked at: {0}'.format(revocation_second))

Java

// Revoke all refresh tokens for a specified user in a specified tenant for whatever reason.
// Retrieve the timestamp of the revocation, in seconds since the epoch.
tenantAuth.revokeRefreshTokens(uid);

// accessing the user's TokenValidAfter
UserRecord user = tenantAuth.getUser(uid);

long timestamp = user.getTokensValidAfterTimestamp() / 1000;
System.out.println("the refresh tokens were revoked at: " + timestamp + " (UTC seconds)");

Nach dem Widerrufen der Aktualisierungstoken können für diesen Nutzer keine neuen ID-Token ausgestellt werden, bis eine neue Authentifizierung erfolgt. Vorhandene ID-Tokens bleiben jedoch bis zur natürlichen Ablaufzeit (eine Stunde) aktiv.

Sie können prüfen, ob ein nicht abgelaufenes ID-Token nicht widerrufen wurde, indem Sie den optionalen Parameter checkRevoked angeben. Damit wird geprüft, ob ein Token widerrufen wird, nachdem seine Integrität und Authentizität geprüft wurden.

Node.js

// Verify the ID token for a specific tenant while checking if the token is revoked by passing
// checkRevoked true.
let checkRevoked = true;
tenantAuth.verifyIdToken(idToken, checkRevoked)
  .then(payload => {
    // Token is valid.
  })
  .catch(error => {
    if (error.code == 'auth/id-token-revoked') {
      // Token has been revoked. Inform the user to re-authenticate or
      // signOut() the user.
    } else {
      // Token is invalid.
    }
  });

Python

	# Verify the ID token for a specific tenant while checking if the token is revoked.
    try:
        # Verify the ID token while checking if the token is revoked by
        # passing check_revoked=True.
        decoded_token = tenant_client.verify_id_token(id_token, check_revoked=True)
        # Token is valid and not revoked.
        uid = decoded_token['uid']
    except tenant_mgt.TenantIdMismatchError:
        # Token belongs to a different tenant.
        pass
    except auth.RevokedIdTokenError:
        # Token revoked, inform the user to reauthenticate or signOut().
        pass
    except auth.UserDisabledError:
        # Token belongs to a disabled user record.
        pass
    except auth.InvalidIdTokenError:
        # Token is invalid
        pass

Java

// Verify the ID token for a specific tenant while checking if the token is revoked.
boolean checkRevoked = true;
try {
  FirebaseToken token = tenantAuth.verifyIdToken(idToken, checkRevoked);
  System.out.println("Verified ID token for: " + token.getUid());
} catch (FirebaseAuthException e) {
  if ("id-token-revoked".equals(e.getErrorCode())) {
    // Token is revoked. Inform the user to re-authenticate or signOut() the user.
  } else {
    // Token is invalid
  }
}

Weitere Informationen finden Sie in der Admin SDK-Dokumentation unter Sitzungen verwalten.

Zugriff mit benutzerdefinierten Anforderungen steuern

Das Admin SDK unterstützt die Definition benutzerdefinierter Attribute in Nutzerkonten für einen bestimmten Mandanten. Mit diesen Attributen können Sie verschiedene Zugriffssteuerungsstrategien implementieren, z. B. rollenbasierte Zugriffssteuerung. Mithilfe der Attribute können Sie Nutzern unterschiedliche Zugriffsebenen zuweisen, die von den Sicherheitsregeln der Anwendung erzwungen werden.

Rufen Sie zuerst eine TenantAwareAuth-Instanz für den entsprechenden Mandanten ab:

Node.js

const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');

Python

tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')

Java

TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager()
    .getAuthForTenant("TENANT-ID");

Benutzerdefinierte Anforderungen können sensible Daten enthalten, daher sollten sie nur mithilfe des Admin SDK über eine privilegierte Serverumgebung festgelegt werden.

Node.js

// Set admin privilege on the user corresponding to uid for a specific tenant.
tenantAuth.setCustomUserClaims(uid, {admin: true}).then(() => {
  // The new custom claims will propagate to the user's ID token the
  // next time a new one is issued.
});

Python

# Set admin privilege on the user corresponding to uid.
tenant_client.set_custom_user_claims(uid, {'admin': True})
# The new custom claims will propagate to the user's ID token the
# next time a new one is issued.

Java

// Set admin privilege on the user corresponding to uid in a specific tenant.
Map<String, Object> claims = new HashMap<>();
claims.put("admin", true);
tenantAuth.setCustomUserClaims(uid, claims);
// The new custom claims will propagate to the user's ID token the
// next time a new one is issued.

Neu festgelegte benutzerdefinierte Attribute werden in den Attributen der obersten Ebene der Tokennutzlast angezeigt, wenn sich der Nutzer das nächste Mal anmeldet oder seine ID-Tokens in einer vorhandenen Sitzung aktualisiert. Im vorherigen Beispiel enthält das ID-Token die zusätzliche Anforderung {admin: true}.

Nach der Prüfung des ID-Tokens und der Decodierung der Nutzlast können diese zusätzlichen benutzerdefinierten Anforderungen geprüft werden, um die Zugriffssteuerung zu erzwingen.

Node.js

// Verify the ID token first.
tenantAuth.verifyIdToken(idToken).then((claims) => {
  if (claims.admin === true) {
    // Allow access to requested admin resource.
  }
});

Python

# Verify the ID token first.
claims = tenant_client.verify_id_token(id_token)
if claims['admin'] is True:
    # Allow access to requested admin resource.
    pass

Java

// Verify the ID token first.
FirebaseToken token = tenantAuth.verifyIdToken(idToken);
if (Boolean.TRUE.equals(token.getClaims().get("admin"))) {
  //Allow access to requested admin resource.
}
// Verify the ID token first.
FirebaseToken decoded = tenantAuth.verifyIdToken(idToken);
if (Boolean.TRUE.equals(decoded.getClaims().get("admin"))) {
  // Allow access to requested admin resource.
}

Benutzerdefinierte Anforderungen für einen vorhandenen Nutzer für einen bestimmten Mandanten sind auch als Attribut für den Nutzerdatensatz verfügbar.

Node.js

// Lookup the user associated with the specified uid.
tenantAuth.getUser(uid).then((userRecord) => {
  // The claims can be accessed on the user record.
  console.log(userRecord.customClaims.admin);
});

Python

	# Lookup the user associated with the specified uid.
    user = tenant_client.get_user(uid)

	# The claims can be accessed on the user record.
    print(user.custom_claims.get('admin'))

Java

// Lookup the user associated with the specified uid in a specific tenant.
UserRecord user = tenantAuth.getUser(uid);
System.out.println(user.getCustomClaims().get("admin"));

Weitere Informationen finden Sie in der Admin SDK-Dokumentation unter Benutzerdefinierte Anforderungen.

Mit den Identity Platform-Client-SDKs können Sie Nutzern eines bestimmten Mandanten E-Mails mit Links zum Zurücksetzen von Passwörtern, zur Bestätigung der E-Mail-Adresse und zur Anmeldung per E-Mail senden. Diese E-Mails werden von Google gesendet und können nur beschränkt angepasst werden.

Mit dem Admin SDK können Sie diese Links programmatisch im Bereich eines bestimmten Mandanten generieren.

Rufen Sie zuerst eine TenantAwareAuth-Instanz für den entsprechenden Mandanten ab:

Node.js

const tenantAuth = admin.auth().tenantManager().authForTenant('TENANT-ID');

Python

tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')

Java

TenantAwareFirebaseAuth tenantAuth = FirebaseAuth.getInstance().getTenantManager()
    .getAuthForTenant("TENANT-ID");

Das folgende Beispiel zeigt, wie Sie einen Link generieren, um die E-Mail-Adresse eines Nutzers für einen angegebenen Mandanten zu bestätigen:

Node.js

const actionCodeSettings = {
  // URL you want to redirect back to. The domain (www.example.com) for
  // this URL must be whitelisted in the Cloud console.
  url: 'https://www.example.com/checkout?cartId=1234',
  // This must be true for email link sign-in.
  handleCodeInApp: true,
  iOS: {
    bundleId: 'com.example.ios'
  },
  android: {
    packageName: 'com.example.android',
    installApp: true,
    minimumVersion: '12'
  },
  // FDL custom domain.
  dynamicLinkDomain: 'coolapp.page.link'
};

// Admin SDK API to generate the email verification link.
const userEmail = 'user@example.com';
tenantAuth.generateEmailVerificationLink(userEmail, actionCodeSettings)
  .then((link) => {
    // Construct email verification template, embed the link and send
    // using custom SMTP server.
    return sendCustomVerificationEmail(userEmail, displayName, link);
  })
  .catch((error) => {
    // Some error occurred.
  });

Python

action_code_settings = auth.ActionCodeSettings(
    url='https://www.example.com/checkout?cartId=1234',
    handle_code_in_app=True,
    ios_bundle_id='com.example.ios',
    android_package_name='com.example.android',
    android_install_app=True,
    android_minimum_version='12',
    # FDL custom domain.
    dynamic_link_domain='coolapp.page.link',
)

email = 'user@example.com'
link = tenant_client.generate_email_verification_link(email, action_code_settings)
# Construct email from a template embedding the link, and send
# using a custom SMTP server.
send_custom_email(email, link)

Java

ActionCodeSettings actionCodeSettings = ActionCodeSettings.builder()
    // URL you want to redirect back to. The domain (www.example.com) for
    // this URL must be whitelisted in the GCP Console.
    .setUrl("https://www.example.com/checkout?cartId=1234")
    // This must be true for email link sign-in.
    .setHandleCodeInApp(true)
    .setIosBundleId("com.example.ios")
    .setAndroidPackageName("com.example.android")
    .setAndroidInstallApp(true)
    .setAndroidMinimumVersion("12")
    // FDL custom domain.
    .setDynamicLinkDomain("coolapp.page.link")
    .build();

String link = tenantAuth.generateEmailVerificationLink(email, actionCodeSettings);

// Construct email verification template, embed the link and send
// using custom SMTP server.
sendCustomEmail(email, displayName, link);

Es gibt ähnliche Mechanismen, mit denen sich Links für das Zurücksetzen von Passwörtern und E-Mail-basierte Anmeldelinks generieren lassen. Beim Generieren eines E-Mail-Aktions-Links in einem Mandantenkontext muss die Mandanten-ID aus dem Link geparst und in der Client-Instanz Auth festgelegt werden, bevor der Code angewendet werden kann.

const actionCodeUrl = firebase.auth.ActionCodeURL.parseLink(window.location.href);
// A one-time code, used to identify and verify a request.
const code = actionCodeUrl.code;
// The tenant ID being used to trigger the email action.
const tenantId = actionCodeUrl.tenantId;
auth.tenantId = tenantId;

// Apply the action code.
auth.applyActionCode(actionCode)
  .then(() => {
    // User's email is now verified.
  })
  .catch((error) => {
    // Handle error.
  });

Weitere Informationen finden Sie in der Admin SDK-Dokumentation unter E-Mail-Aktion-links.

Fehlermeldungen

In der folgenden Tabelle sind häufig auftretende Fehlermeldungen aufgeführt.

Fehlercode Beschreibung und Lösungsschritte
auth/billing-not-enabled Für dieses Feature muss die Abrechnung aktiviert sein.
auth/invalid-display-name Das Feld "displayName" muss ein gültiger String sein.
auth/invalid-name Der angegebene Ressourcenname ist ungültig.
auth/invalid-page-token Das Seitentoken muss eine gültige, nicht leere Zeichenfolge sein.
auth/invalid-project-id Ungültiges übergeordnetes Projekt. Entweder ermöglicht oder ermöglichte das übergeordnete Projekt die Mehrmandantenfähigkeit nicht.
auth/invalid-tenant-id Die Mandanten-ID muss ein gültiger, nicht leerer String sein.
auth/mismatching-tenant-id Die Nutzer-Mandanten-ID stimmt nicht mit der aktuellen Mandanten-ID TenantAwareAuth überein.
auth/missing-display-name Die Ressource, die erstellt oder bearbeitet wird, hat keinen gültigen Anzeigenamen.
auth/insufficient-permission Der Nutzer ist nicht berechtigt, auf die angeforderte Ressource zuzugreifen oder den jeweiligen Mandantenvorgang auszuführen.
auth/quota-exceeded Das Projektkontingent für den angegebenen Vorgang wurde überschritten.
auth/tenant-not-found Es ist kein Mandanten vorhanden, der mit der angegebenen ID übereinstimmt.
auth/unsupported-tenant-operation Dieser Vorgang wird in einem mandantenfähigen Kontext nicht unterstützt.
auth/invalid-testing-phone-number Es wurde eine ungültige Testtelefonnummer oder ein ungültiger Testcode angegeben.
auth/test-phone-number-limit-exceeded Die maximal zulässige Anzahl von Testtelefonnummern und -codepaaren wurde überschritten.