Google is committed to advancing racial equity for Black communities. See how.
Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Erstellen Sie benutzerdefinierte Token

Mit Firebase haben Sie die vollständige Kontrolle über die Authentifizierung, indem Sie Benutzer oder Geräte mithilfe sicherer JSON-Web-Tokens (JWTs) authentifizieren können. Sie generieren diese Token auf Ihrem Server, geben sie an ein signInWithCustomToken() und verwenden sie dann zur Authentifizierung über die signInWithCustomToken() -Methode.

Um dies zu erreichen, müssen Sie einen Serverendpunkt erstellen, der Anmeldeinformationen akzeptiert, z. B. einen Benutzernamen und ein Kennwort. Wenn die Anmeldeinformationen gültig sind, wird ein benutzerdefiniertes JWT zurückgegeben. Das von Ihrem Server zurückgegebene benutzerdefinierte JWT kann dann von einem Clientgerät zur Authentifizierung bei Firebase ( iOS , Android , Web ) verwendet werden. Nach der Authentifizierung wird diese Identität beim Zugriff auf andere Firebase-Dienste wie die Firebase-Echtzeitdatenbank und den Cloud-Speicher verwendet. Darüber hinaus ist der Inhalt des JWT im auth Objekt in Ihren Echtzeitdatenbankregeln und im request.auth Objekt in Ihren Cloud Storage-Sicherheitsregeln request.auth .

Sie können ein benutzerdefiniertes Token mit dem Firebase Admin SDK erstellen oder eine JWT-Bibliothek eines Drittanbieters verwenden, wenn Ihr Server in einer Sprache geschrieben ist, die Firebase nicht nativ unterstützt.

Bevor Sie beginnen

Benutzerdefinierte Token sind signierte JWTs, bei denen der zum Signieren verwendete private Schlüssel zu einem Google-Dienstkonto gehört. Es gibt verschiedene Möglichkeiten, das Google-Dienstkonto anzugeben, das vom Firebase Admin SDK zum Signieren benutzerdefinierter Token verwendet werden soll:

  • Verwenden einer JSON-Datei für ein Dienstkonto - Diese Methode kann in jeder Umgebung verwendet werden, erfordert jedoch, dass Sie eine JSON-Datei für ein Dienstkonto zusammen mit Ihrem Code verpacken. Es muss besonders darauf geachtet werden, dass die JSON-Datei des Dienstkontos keinen externen Parteien zugänglich gemacht wird.
  • Ermöglichen, dass das Admin SDK ein Dienstkonto erkennt - Diese Methode kann in von Google verwalteten Umgebungen wie Google Cloud Functions und App Engine verwendet werden. Möglicherweise müssen Sie einige zusätzliche Berechtigungen über die Google Cloud Console konfigurieren.
  • Verwenden einer Dienstkonto-ID - Bei Verwendung in einer von Google verwalteten Umgebung signiert diese Methode Token mit dem Schlüssel des angegebenen Dienstkontos. Es wird jedoch ein Remote-Webdienst verwendet, und Sie müssen möglicherweise zusätzliche Berechtigungen für dieses Dienstkonto über die Google Cloud Console konfigurieren.

Verwenden einer JSON-Datei für ein Dienstkonto

JSON-Dateien für Dienstkonten enthalten alle Informationen, die Dienstkonten entsprechen (einschließlich des privaten RSA-Schlüssels). Sie können von der Firebase-Konsole heruntergeladen werden. Befolgen Sie die Anweisungen zum Einrichten des Admin SDK, um weitere Informationen zum Initialisieren des Admin SDK mit einer JSON-Datei für das Dienstkonto zu erhalten.

Diese Initialisierungsmethode eignet sich für eine Vielzahl von Admin SDK-Bereitstellungen. Außerdem kann das Admin SDK benutzerdefinierte Token lokal erstellen und signieren, ohne Remote-API-Aufrufe durchführen zu müssen. Der Hauptnachteil dieses Ansatzes besteht darin, dass Sie eine JSON-Datei für das Dienstkonto zusammen mit Ihrem Code verpacken müssen. Beachten Sie auch, dass der private Schlüssel in einer JSON-Datei des Dienstkontos vertrauliche Informationen sind und dass besondere Sorgfalt darauf verwendet werden muss, diese vertraulich zu behandeln. Vermeiden Sie insbesondere das Hinzufügen von JSON-Dateien für Dienstkonten zur öffentlichen Versionskontrolle.

Lassen Sie das Admin SDK ein Dienstkonto erkennen

Wenn Ihr Code in einer von Google verwalteten Umgebung bereitgestellt wird, kann das Admin-SDK versuchen, ein Mittel zum Signieren benutzerdefinierter Token automatisch zu ermitteln:

  • Wenn Ihr Code in der App Engine-Standardumgebung für Java, Python oder Go bereitgestellt wird, kann das Admin SDK den in dieser Umgebung vorhandenen App Identity-Dienst zum Signieren benutzerdefinierter Token verwenden. Der App Identity-Dienst signiert Daten mithilfe eines Dienstkontos, das von Google App Engine für Ihre App bereitgestellt wird.

  • Wenn Ihr Code in einer anderen verwalteten Umgebung bereitgestellt wird (z. B. Google Cloud-Funktionen, Google Compute Engine), kann das Firebase Admin SDK eine Dienstkonto-ID-Zeichenfolge vom lokalen Metadatenserver automatisch erkennen. Die ID des erkannten Dienstkontos wird dann in Verbindung mit dem IAM-Dienst verwendet, um Token remote zu signieren.

Um diese Signaturmethoden zu verwenden, initialisieren Sie das SDK mit den Standardanmeldeinformationen von Google Application und geben Sie keine ID-Zeichenfolge für das Dienstkonto an:

Node.js

admin.initializeApp();

Java

FirebaseApp.initializeApp();

Python

default_app = firebase_admin.initialize_app()

Gehen

app, err := firebase.NewApp(context.Background(), nil)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

C #

FirebaseApp.Create();

Um denselben Code lokal zu testen, laden Sie eine JSON-Datei für das GOOGLE_APPLICATION_CREDENTIALS herunter und setzen Sie die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS so, dass sie darauf GOOGLE_APPLICATION_CREDENTIALS .

Wenn das Firebase Admin SDK eine Dienstkonto-ID-Zeichenfolge ermitteln muss, geschieht dies, wenn Ihr Code zum ersten Mal ein benutzerdefiniertes Token erstellt. Das Ergebnis wird zwischengespeichert und für nachfolgende Token-Signaturvorgänge wiederverwendet. Die automatisch erkannte Dienstkonto-ID ist normalerweise eines der Standarddienstkonten, die von der Google Cloud bereitgestellt werden:

Genau wie bei explizit angegebenen Dienstkonto-IDs müssen automatisch iam.serviceAccounts.signBlob Dienstkonto-IDs über die iam.serviceAccounts.signBlob verfügen, damit die iam.serviceAccounts.signBlob funktioniert. Möglicherweise müssen Sie den Abschnitt IAM und Admin der Google Cloud Console verwenden, um den Standarddienstkonten die erforderlichen Berechtigungen zu erteilen. Weitere Informationen finden Sie im Abschnitt zur Fehlerbehebung.

Verwenden einer Dienstkonto-ID

Um die Konsistenz zwischen verschiedenen Teilen Ihrer Anwendung zu gewährleisten, können Sie eine Dienstkonto-ID angeben, deren Schlüssel zum Signieren von Token verwendet werden, wenn diese in einer von Google verwalteten Umgebung ausgeführt werden. Dies kann IAM-Richtlinien einfacher und sicherer machen und vermeiden, dass die JSON-Datei des Dienstkontos in Ihren Code aufgenommen werden muss.

Die Dienstkonto-ID finden Sie in der Google Cloud Console oder im Feld client_email einer heruntergeladenen JSON-Datei für das client_email . <client-id>@<project-id>.iam.gserviceaccount.com IDs sind E-Mail-Adressen im folgenden Format: <client-id>@<project-id>.iam.gserviceaccount.com . Sie identifizieren Dienstkonten in Firebase- und Google Cloud-Projekten eindeutig.

Initialisieren Sie das SDK wie folgt, um benutzerdefinierte Token mit einer separaten Dienstkonto-ID zu erstellen:

Node.js

admin.initializeApp({
  serviceAccountId: 'my-client-id@my-project-id.iam.gserviceaccount.com',
});

Java

FirebaseOptions options = FirebaseOptions.builder()
    .setCredentials(GoogleCredentials.getApplicationDefault())
    .setServiceAccountId("my-client-id@my-project-id.iam.gserviceaccount.com")
    .build();
FirebaseApp.initializeApp(options);

Python

options = {
    'serviceAccountId': 'my-client-id@my-project-id.iam.gserviceaccount.com',
}
firebase_admin.initialize_app(options=options)

Gehen

conf := &firebase.Config{
	ServiceAccountID: "my-client-id@my-project-id.iam.gserviceaccount.com",
}
app, err := firebase.NewApp(context.Background(), conf)
if err != nil {
	log.Fatalf("error initializing app: %v\n", err)
}

C #

FirebaseApp.Create(new AppOptions()
{
    Credential = GoogleCredential.GetApplicationDefault(),
    ServiceAccountId = "my-client-id@my-project-id.iam.gserviceaccount.com",
});

Dienstkonto-IDs sind keine vertraulichen Informationen, weshalb ihre Offenlegung keine Rolle spielt. Um benutzerdefinierte Token mit dem angegebenen Dienstkonto zu signieren, muss das Firebase Admin SDK jedoch einen Remotedienst aufrufen. Darüber hinaus müssen Sie auch sicherstellen, dass das Dienstkonto das Admin SDK diesen Aufruf -Normalerweise machen wird mit {project-name}@appspot.gserviceaccount.com - hat die iam.serviceAccounts.signBlob Erlaubnis . Weitere Informationen finden Sie im Abschnitt zur Fehlerbehebung.

Erstellen Sie benutzerdefinierte Token mit dem Firebase Admin SDK

Das Firebase Admin SDK verfügt über eine integrierte Methode zum Erstellen benutzerdefinierter Token. Sie müssen mindestens eine uid , bei der es sich um eine beliebige Zeichenfolge uid , die jedoch den Benutzer oder das Gerät, das Sie authentifizieren, eindeutig identifizieren soll. Diese Token verfallen nach einer Stunde.

Node.js

const uid = 'some-uid';

admin
  .auth()
  .createCustomToken(uid)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

Java

String uid = "some-uid";

String customToken = FirebaseAuth.getInstance().createCustomToken(uid);
// Send token back to client

Python

uid = 'some-uid'

custom_token = auth.create_custom_token(uid)

Gehen

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

token, err := client.CustomToken(ctx, "some-uid")
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

C #

var uid = "some-uid";

string customToken = await FirebaseAuth.DefaultInstance.CreateCustomTokenAsync(uid);
// Send token back to client

Optional können Sie auch zusätzliche Ansprüche angeben, die in das benutzerdefinierte Token aufgenommen werden sollen. Im Folgenden wurde premiumAccount Feld " premiumAccount ein benutzerdefiniertes Token hinzugefügt, das in den Objekten auth / request.auth in Ihren Sicherheitsregeln verfügbar ist:

Node.js

const userId = 'some-uid';
const additionalClaims = {
  premiumAccount: true,
};

admin
  .auth()
  .createCustomToken(userId, additionalClaims)
  .then((customToken) => {
    // Send token back to client
  })
  .catch((error) => {
    console.log('Error creating custom token:', error);
  });

Java

String uid = "some-uid";
Map<String, Object> additionalClaims = new HashMap<String, Object>();
additionalClaims.put("premiumAccount", true);

String customToken = FirebaseAuth.getInstance()
    .createCustomToken(uid, additionalClaims);
// Send token back to client

Python

uid = 'some-uid'
additional_claims = {
    'premiumAccount': True
}

custom_token = auth.create_custom_token(uid, additional_claims)

Gehen

client, err := app.Auth(context.Background())
if err != nil {
	log.Fatalf("error getting Auth client: %v\n", err)
}

claims := map[string]interface{}{
	"premiumAccount": true,
}

token, err := client.CustomTokenWithClaims(ctx, "some-uid", claims)
if err != nil {
	log.Fatalf("error minting custom token: %v\n", err)
}

log.Printf("Got custom token: %v\n", token)

C #

var uid = "some-uid";
var additionalClaims = new Dictionary<string, object>()
{
    { "premiumAccount", true },
};

string customToken = await FirebaseAuth.DefaultInstance
    .CreateCustomTokenAsync(uid, additionalClaims);
// Send token back to client

Melden Sie sich mit benutzerdefinierten Token auf Clients an

Nachdem Sie ein benutzerdefiniertes Token erstellt haben, sollten Sie es an Ihre Client-App senden. Die Client-App authentifiziert sich mit dem benutzerdefinierten Token, indem sie signInWithCustomToken() :

iOS

Ziel c
[[FIRAuth auth] signInWithCustomToken:customToken
                           completion:^(FIRAuthDataResult * _Nullable authResult,
                                        NSError * _Nullable error) {
  // ...
}];
Schnell
Auth.auth().signIn(withCustomToken: customToken ?? "") { (user, error) in
  // ...
}

Android

mAuth.signInWithCustomToken(mCustomToken)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCustomToken:success");
                    FirebaseUser user = mAuth.getCurrentUser();
                    updateUI(user);
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(TAG, "signInWithCustomToken:failure", task.getException());
                    Toast.makeText(CustomAuthActivity.this, "Authentication failed.",
                            Toast.LENGTH_SHORT).show();
                    updateUI(null);
                }
            }
        });

Einheit

auth.SignInWithCustomTokenAsync(custom_token).ContinueWith(task => {
  if (task.IsCanceled) {
    Debug.LogError("SignInWithCustomTokenAsync was canceled.");
    return;
  }
  if (task.IsFaulted) {
    Debug.LogError("SignInWithCustomTokenAsync encountered an error: " + task.Exception);
    return;
  }

  Firebase.Auth.FirebaseUser newUser = task.Result;
  Debug.LogFormat("User signed in successfully: {0} ({1})",
      newUser.DisplayName, newUser.UserId);
});

C ++

firebase::Future<firebase::auth::User*> result =
    auth->SignInWithCustomToken(custom_token);

Netz

firebase.auth().signInWithCustomToken(token)
  .then((userCredential) => {
    // Signed in
    var user = userCredential.user;
    // ...
  })
  .catch((error) => {
    var errorCode = error.code;
    var errorMessage = error.message;
    // ...
  });

Wenn die Authentifizierung erfolgreich ist, wird Ihr Benutzer jetzt mit dem Konto, das durch die im benutzerdefinierten Token enthaltene uid angegeben wird, bei Ihrer Client-App uid . Wenn dieses Konto zuvor nicht vorhanden war, wird ein Datensatz für diesen Benutzer erstellt.

Auf die gleiche Weise wie bei anderen signInWithEmailAndPassword() (wie signInWithEmailAndPassword() und signInWithCredential() ) werden das auth Objekt in Ihren Echtzeitdatenbankregeln und das request.auth Objekt in Ihren Cloud Storage-Sicherheitsregeln mit der Benutzer- uid . In diesem Fall ist die uid diejenige, die Sie beim Generieren des benutzerdefinierten Tokens angegeben haben.

Datenbankregeln

{
  "rules": {
    "adminContent": {
      ".read": "auth.uid === 'some-uid'"
    }
  }
}

Speicherregeln

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /adminContent/{filename} {
      allow read, write: if request.auth != null && request.auth.uid == "some-uid";
    }
  }
}

Wenn das benutzerdefinierte Token zusätzliche Ansprüche enthält, können Sie in Ihren Regeln auf das Objekt auth.token (Firebase Realtime Database) oder request.auth.token (Cloud Storage) request.auth.token :

Datenbankregeln

{
  "rules": {
    "premiumContent": {
      ".read": "auth.token.premiumAccount === true"
    }
  }
}

Speicherregeln

service firebase.storage {
  match /b/<your-firebase-storage-bucket>/o {
    match /premiumContent/{filename} {
      allow read, write: if request.auth.token.premiumAccount == true;
    }
  }
}

Erstellen Sie benutzerdefinierte Token mithilfe einer JWT-Bibliothek eines Drittanbieters

Wenn Ihr Backend in einer Sprache ohne offizielles Firebase Admin SDK vorliegt, können Sie dennoch manuell benutzerdefinierte Token erstellen. Suchen Sie zunächst eine JWT-Bibliothek eines Drittanbieters für Ihre Sprache. Verwenden Sie dann diese JWT-Bibliothek, um eine JWT zu prägen, die die folgenden Ansprüche enthält:

Benutzerdefinierte Token-Ansprüche
alg Algorithmus "RS256"
iss Aussteller E-Mail-Adresse des Dienstkontos Ihres Projekts
sub Gegenstand E-Mail-Adresse des Dienstkontos Ihres Projekts
aud Publikum "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat Ausgestellt zum Zeitpunkt Die aktuelle Zeit in Sekunden seit der UNIX-Epoche
exp Ablaufzeit Die Zeit in Sekunden seit der UNIX-Epoche, zu der das Token abläuft. Es kann maximal 3600 Sekunden später als das iat .
Hinweis: Dies steuert nur die Zeit, zu der das benutzerdefinierte Token selbst abläuft. Sobald Sie einen Benutzer mit signInWithCustomToken() , bleibt er am Gerät angemeldet, bis seine Sitzung ungültig wird oder der Benutzer sich signInWithCustomToken() .
uid Die eindeutige Kennung des angemeldeten Benutzers muss eine Zeichenfolge mit einer Länge zwischen 1 und 36 Zeichen sein
claims (optional) Optionale benutzerdefinierte Ansprüche, die in die Variablen auth / request.auth der Sicherheitsregeln request.auth werden sollen

Im Folgenden finden Sie einige Beispielimplementierungen zum Erstellen benutzerdefinierter Token in verschiedenen Sprachen, die vom Firebase Admin SDK nicht unterstützt werden:

PHP

Verwenden von php-jwt :

// Requires: composer require firebase/php-jwt
use Firebase\JWT\JWT;

// Get your service account's email address and private key from the JSON key file
$service_account_email = "abc-123@a-b-c-123.iam.gserviceaccount.com";
$private_key = "-----BEGIN PRIVATE KEY-----...";

function create_custom_token($uid, $is_premium_account) {
  global $service_account_email, $private_key;

  $now_seconds = time();
  $payload = array(
    "iss" => $service_account_email,
    "sub" => $service_account_email,
    "aud" => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
    "iat" => $now_seconds,
    "exp" => $now_seconds+(60*60),  // Maximum expiration time is one hour
    "uid" => $uid,
    "claims" => array(
      "premium_account" => $is_premium_account
    )
  );
  return JWT::encode($payload, $private_key, "RS256");
}

Rubin

Mit ruby-jwt :

require "jwt"

# Get your service account's email address and private key from the JSON key file
$service_account_email = "service-account@my-project-abc123.iam.gserviceaccount.com"
$private_key = OpenSSL::PKey::RSA.new "-----BEGIN PRIVATE KEY-----\n..."

def create_custom_token(uid, is_premium_account)
  now_seconds = Time.now.to_i
  payload = {:iss => $service_account_email,
             :sub => $service_account_email,
             :aud => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
             :iat => now_seconds,
             :exp => now_seconds+(60*60), # Maximum expiration time is one hour
             :uid => uid,
             :claims => {:premium_account => is_premium_account}}
  JWT.encode payload, $private_key, "RS256"
end

Nachdem Sie das benutzerdefinierte Token erstellt haben, senden Sie es an Ihre Client-App, um sich bei Firebase zu authentifizieren. Informationen dazu finden Sie in den obigen Codebeispielen.

Fehlerbehebung

In diesem Abschnitt werden einige häufig auftretende Probleme beschrieben, auf die Entwickler beim Erstellen benutzerdefinierter Token stoßen können, und wie diese behoben werden können.

IAM-API nicht aktiviert

Wenn Sie eine Dienstkonto-ID zum Signieren von Token angeben, wird möglicherweise ein Fehler angezeigt, der dem folgenden ähnelt:

Identity and Access Management (IAM) API has not been used in project
1234567890 before or it is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/iam.googleapis.com/overview?project=1234567890
then retry. If you enabled this API recently, wait a few minutes for the action
to propagate to our systems and retry.

Das Firebase Admin SDK verwendet die IAM-API zum Signieren von Token. Dieser Fehler zeigt an, dass die IAM-API derzeit nicht für Ihr Firebase-Projekt aktiviert ist. Öffnen Sie den Link in der Fehlermeldung in einem Webbrowser und klicken Sie auf die Schaltfläche "API aktivieren", um ihn für Ihr Projekt zu aktivieren.

Für das Dienstkonto sind keine Berechtigungen erforderlich

Wenn das Dienstkonto, auf dem das Firebase Admin SDK ausgeführt wird, nicht über die iam.serviceAccounts.signBlob , wird möglicherweise eine Fehlermeldung wie die folgende angezeigt:

Permission iam.serviceAccounts.signBlob is required to perform this operation
on service account projects/-/serviceAccounts/{your-service-account-id}.

Der einfachste Weg, dies zu beheben, besteht darin, dem betreffenden {project-name}@appspot.gserviceaccount.com IAM-Rolle "Service Account Token Creator" {project-name}@appspot.gserviceaccount.com , normalerweise {project-name}@appspot.gserviceaccount.com :

  1. Öffnen Sie die IAM- und Administrationsseite in der Google Cloud Console.
  2. Wählen Sie Ihr Projekt aus und klicken Sie auf "Weiter".
  3. Klicken Sie auf das Bearbeitungssymbol für das Dienstkonto, das Sie aktualisieren möchten.
  4. Klicken Sie auf "Weitere Rolle hinzufügen".
  5. Geben Sie "Service Account Token Creator" in den Suchfilter ein und wählen Sie ihn aus den Ergebnissen aus.
  6. Klicken Sie auf "Speichern", um die Rollengewährung zu bestätigen.

Weitere Informationen zu diesem Prozess finden Sie in der IAM-Dokumentation. Außerdem erfahren Sie, wie Sie Rollen mithilfe der Befehlszeilentools von gcloud aktualisieren.

Dienstkonto konnte nicht ermittelt werden

Wenn eine Fehlermeldung ähnlich der folgenden angezeigt wird, wurde das Firebase Admin SDK nicht ordnungsgemäß initialisiert.

Failed to determine service account ID. Initialize the SDK with service account
credentials or specify a service account ID with iam.serviceAccounts.signBlob
permission.

Wenn Sie sich beim automatischen Erkennen einer Dienstkonto-ID auf das SDK verlassen, stellen Sie sicher, dass der Code in einer verwalteten Google-Umgebung mit einem Metadatenserver bereitgestellt wird. Andernfalls müssen Sie bei der SDK-Initialisierung die JSON-Datei des Dienstkontos oder die Dienstkonto-ID angeben.