Blockhaus

Viele Nutzer verwalten ihre Anmeldedaten beim Einrichten eines neuen Android-Geräts immer noch selbst . Dieser manuelle Prozess kann schwierig werden und führt oft zu einer schlechten User Experience ausmacht. Block Store API, eine Bibliothek von Google Play , um dieses Problem zu lösen, indem sie Apps die Möglichkeit bietet, Anmeldedaten von Nutzern ohne die Komplexität oder das Sicherheitsrisiko, das mit der Speicherung Nutzerpasswörter.

Mit der Block Store API kann Ihre Anwendung Daten speichern, die später benötigt werden abrufen, um Nutzer auf einem neuen Gerät noch einmal zu authentifizieren. Dies trägt dazu bei, eine die nahtlose Nutzererfahrung bieten, da sie keinen Anmeldebildschirm sehen müssen wenn du deine App zum ersten Mal auf dem neuen Gerät startest.

Die Verwendung von Block Store bietet unter anderem folgende Vorteile:

  • Verschlüsselte Anmeldedatenspeicherlösung für Entwickler Anmeldedaten sind wenn möglich mit Ende-zu-Ende-Verschlüsselung.
  • Speichern Sie Tokens anstelle von Nutzernamen und Passwörtern.
  • Sorgen Sie für eine reibungslose Anmeldung.
  • Ersparen Sie Nutzern die Verwaltung komplexer Passwörter.
  • Google überprüft die Identität des Nutzers.

Hinweis

Führen Sie die Schritte in den folgenden Abschnitten aus, um Ihre App vorzubereiten.

Eigene App konfigurieren

Fügen Sie in die Datei build.gradle auf Projektebene das Maven von Google ein. Repository in beidenbuildscript und allprojects:

buildscript {
  repositories {
    google()
    mavenCentral()
  }
}

allprojects {
  repositories {
    google()
    mavenCentral()
  }
}

Google Play-Dienste hinzufügen Abhängigkeit für die Block Store API zu Ihrem Gradle-Build-Datei des Moduls Dies ist üblicherweise app/build.gradle:

dependencies {
  implementation 'com.google.android.gms:play-services-auth-blockstore:16.3.1'
}

Funktionsweise

Block Store ermöglicht es Entwicklern, bis zu 16-Byte-Arrays zu speichern und wiederherzustellen. So können Sie wichtige Informationen zur aktuellen Nutzersitzung speichern und diese Informationen nach Belieben speichern. Diese Daten können mit Ende-zu-Ende-Verschlüsselung geschützt werden und die Infrastruktur, die Block Store unterstützt, baut auf der Backup and Restore-Infrastruktur auf.

In diesem Leitfaden wird der Anwendungsfall des Speicherns eines Nutzertokens im Block Store behandelt. Die folgenden Schritte umreißen die Funktionsweise einer App, die den Block Store verwendet:

  1. Während des Authentifizierungsvorgangs Ihrer App oder jederzeit danach können Sie Authentifizierungstoken des Nutzers für den späteren Abruf in Block Store setzen.
  2. Das Token wird lokal gespeichert und kann auch in der Cloud gesichert werden. wenn möglich mit Ende-zu-Ende-Verschlüsselung.
  3. Daten werden übertragen, wenn der Nutzer einen Wiederherstellungsablauf auf einem neuen Gerät initiiert.
  4. Wenn der Nutzer die App während der Wiederherstellung wiederherstellt, hat sie folgende Möglichkeiten: das gespeicherte Token auf dem neuen Gerät aus dem Block Store abrufen.

Token wird gespeichert

Wenn sich ein Nutzer bei Ihrer App anmeldet, können Sie das Authentifizierungstoken, das Sie für diesen Nutzer generieren, in „Store blockieren“ speichern. Sie können dieses Token mit einem eindeutigen Schlüsselpaarwert mit maximal 4 KB pro Eintrag speichern. Rufen Sie zum Speichern des Tokens setBytes() auf. und setKey() auf einer Instanz von StoreBytesData.Builder um die Anmeldedaten des Nutzers auf dem Quellgerät zu speichern. Nach dem Speichern des Tokens mit Block Store wird das Token verschlüsselt und lokal auf dem Gerät gespeichert.

Im folgenden Beispiel wird gezeigt, wie Sie das Authentifizierungstoken in auf dem lokalen Gerät:

Java

  BlockstoreClient client = Blockstore.getClient(this);
  byte[] bytes1 = new byte[] { 1, 2, 3, 4 };  // Store one data block.
  String key1 = "com.example.app.key1";
  StoreBytesData storeRequest1 = StoreBytesData.Builder()
          .setBytes(bytes1)
          // Call this method to set the key value pair the data should be associated with.
          .setKeys(Arrays.asList(key1))
          .build();
  client.storeBytes(storeRequest1)
    .addOnSuccessListener(result -> Log.d(TAG, "stored " + result + " bytes"))
    .addOnFailureListener(e -> Log.e(TAG, "Failed to store bytes", e));

Kotlin

  val client = Blockstore.getClient(this)

  val bytes1 = byteArrayOf(1, 2, 3, 4) // Store one data block.
  val key1 = "com.example.app.key1"
  val storeRequest1 = StoreBytesData.Builder()
    .setBytes(bytes1) // Call this method to set the key value with which the data should be associated with.
    .setKeys(Arrays.asList(key1))
    .build()
  client.storeBytes(storeRequest1)
    .addOnSuccessListener { result: Int ->
      Log.d(TAG,
            "Stored $result bytes")
    }
    .addOnFailureListener { e ->
      Log.e(TAG, "Failed to store bytes", e)
    }

Standardtoken verwenden

Daten, die mit StoreBytes ohne Schlüssel gespeichert werden, verwenden den Standardschlüssel BlockstoreClient.DEFAULT_BYTES_DATA_KEY.

Java

  BlockstoreClient client = Blockstore.getClient(this);
  // The default key BlockstoreClient.DEFAULT_BYTES_DATA_KEY.
  byte[] bytes = new byte[] { 9, 10 };
  StoreBytesData storeRequest = StoreBytesData.Builder()
          .setBytes(bytes)
          .build();
  client.storeBytes(storeRequest)
    .addOnSuccessListener(result -> Log.d(TAG, "stored " + result + " bytes"))
    .addOnFailureListener(e -> Log.e(TAG, "Failed to store bytes", e));

Kotlin

  val client = Blockstore.getClient(this);
  // the default key BlockstoreClient.DEFAULT_BYTES_DATA_KEY.
  val bytes = byteArrayOf(1, 2, 3, 4)
  val storeRequest = StoreBytesData.Builder()
    .setBytes(bytes)
    .build();
  client.storeBytes(storeRequest)
    .addOnSuccessListener { result: Int ->
      Log.d(TAG,
            "stored $result bytes")
    }
    .addOnFailureListener { e ->
      Log.e(TAG, "Failed to store bytes", e)
    }

Token abrufen

Später, wenn ein Nutzer den Wiederherstellungsablauf auf einem neuen überprüft Google Play-Dienste zuerst den Nutzer und ruft dann Ihren Block Daten speichern. Der Nutzer hat der Wiederherstellung Ihrer App-Daten im Rahmen von für die Wiederherstellung, sodass keine zusätzliche Einwilligung erforderlich ist. Wenn der Nutzer die App öffnet App installieren, können Sie Ihr Token vom Block Store anfordern, indem Sie folgenden Befehl aufrufen: retrieveBytes() Das abgerufene Token kann dann verwendet werden, damit der Nutzer auf dem neuen .

Das folgende Beispiel zeigt, wie mehrere Tokens basierend auf bestimmten Schlüsseln abgerufen werden.

Java

BlockstoreClient client = Blockstore.getClient(this);

// Retrieve data associated with certain keys.
String key1 = "com.example.app.key1";
String key2 = "com.example.app.key2";
String key3 = BlockstoreClient.DEFAULT_BYTES_DATA_KEY; // Used to retrieve data stored without a key

List requestedKeys = Arrays.asList(key1, key2, key3); // Add keys to array
RetrieveBytesRequest retrieveRequest = new RetrieveBytesRequest.Builder()
    .setKeys(requestedKeys)
    .build();

client.retrieveBytes(retrieveRequest)
    .addOnSuccessListener(
        result -> {
          Map blockstoreDataMap = result.getBlockstoreDataMap();
          for (Map.Entry entry : blockstoreDataMap.entrySet()) {
            Log.d(TAG, String.format(
                "Retrieved bytes %s associated with key %s.",
                new String(entry.getValue().getBytes()), entry.getKey()));
          }
        })
    .addOnFailureListener(e -> Log.e(TAG, "Failed to store bytes", e));

Kotlin

val client = Blockstore.getClient(this)

// Retrieve data associated with certain keys.
val key1 = "com.example.app.key1"
val key2 = "com.example.app.key2"
val key3 = BlockstoreClient.DEFAULT_BYTES_DATA_KEY // Used to retrieve data stored without a key

val requestedKeys = Arrays.asList(key1, key2, key3) // Add keys to array

val retrieveRequest = RetrieveBytesRequest.Builder()
  .setKeys(requestedKeys)
  .build()

client.retrieveBytes(retrieveRequest)
  .addOnSuccessListener { result: RetrieveBytesResponse ->
    val blockstoreDataMap =
      result.blockstoreDataMap
    for ((key, value) in blockstoreDataMap) {
      Log.d(ContentValues.TAG, String.format(
        "Retrieved bytes %s associated with key %s.",
        String(value.bytes), key))
    }
  }
  .addOnFailureListener { e: Exception? ->
    Log.e(ContentValues.TAG,
          "Failed to store bytes",
          e)
  }

Alle Tokens werden abgerufen.

Im Folgenden finden Sie ein Beispiel dafür, wie alle in BlockStore gespeicherten Tokens abgerufen werden.

Java

BlockstoreClient client = Blockstore.getClient(this)

// Retrieve all data.
RetrieveBytesRequest retrieveRequest = new RetrieveBytesRequest.Builder()
    .setRetrieveAll(true)
    .build();

client.retrieveBytes(retrieveRequest)
    .addOnSuccessListener(
        result -> {
          Map blockstoreDataMap = result.getBlockstoreDataMap();
          for (Map.Entry entry : blockstoreDataMap.entrySet()) {
            Log.d(TAG, String.format(
                "Retrieved bytes %s associated with key %s.",
                new String(entry.getValue().getBytes()), entry.getKey()));
          }
        })
    .addOnFailureListener(e -> Log.e(TAG, "Failed to store bytes", e));

Kotlin

val client = Blockstore.getClient(this)

val retrieveRequest = RetrieveBytesRequest.Builder()
  .setRetrieveAll(true)
  .build()

client.retrieveBytes(retrieveRequest)
  .addOnSuccessListener { result: RetrieveBytesResponse ->
    val blockstoreDataMap =
      result.blockstoreDataMap
    for ((key, value) in blockstoreDataMap) {
      Log.d(ContentValues.TAG, String.format(
        "Retrieved bytes %s associated with key %s.",
        String(value.bytes), key))
    }
  }
  .addOnFailureListener { e: Exception? ->
    Log.e(ContentValues.TAG,
          "Failed to store bytes",
          e)
  }

Im Folgenden finden Sie ein Beispiel für das Abrufen des Standardschlüssels.

Java

BlockStoreClient client = Blockstore.getClient(this);
RetrieveBytesRequest retrieveRequest = new RetrieveBytesRequest.Builder()
    .setKeys(Arrays.asList(BlockstoreClient.DEFAULT_BYTES_DATA_KEY))
    .build();
client.retrieveBytes(retrieveRequest);

Kotlin

val client = Blockstore.getClient(this)

val retrieveRequest = RetrieveBytesRequest.Builder()
  .setKeys(Arrays.asList(BlockstoreClient.DEFAULT_BYTES_DATA_KEY))
  .build()
client.retrieveBytes(retrieveRequest)

Tokens löschen

Das Löschen von Tokens aus BlockStore kann aus den folgenden Gründen erforderlich sein:

  • Der Nutzer durchläuft den User Flow zum Abmelden.
  • Das Token wurde widerrufen oder ist ungültig.

Ähnlich wie beim Abrufen von Tokens können Sie angeben, welche Tokens gelöscht werden müssen, indem Sie ein Array von Schlüsseln festlegen, die gelöscht werden müssen.

Unten sehen Sie ein Beispiel für das Löschen bestimmter Schlüssel.

Java

BlockstoreClient client = Blockstore.getClient(this);

// Delete data associated with certain keys.
String key1 = "com.example.app.key1";
String key2 = "com.example.app.key2";
String key3 = BlockstoreClient.DEFAULT_BYTES_DATA_KEY; // Used to delete data stored without key

List requestedKeys = Arrays.asList(key1, key2, key3) // Add keys to array
DeleteBytesRequest deleteRequest = new DeleteBytesRequest.Builder()
      .setKeys(requestedKeys)
      .build();
client.deleteBytes(deleteRequest)

Kotlin

val client = Blockstore.getClient(this)

// Retrieve data associated with certain keys.
val key1 = "com.example.app.key1"
val key2 = "com.example.app.key2"
val key3 = BlockstoreClient.DEFAULT_BYTES_DATA_KEY // Used to retrieve data stored without a key

val requestedKeys = Arrays.asList(key1, key2, key3) // Add keys to array

val retrieveRequest = DeleteBytesRequest.Builder()
      .setKeys(requestedKeys)
      .build()

client.deleteBytes(retrieveRequest)

Alle Tokens löschen

Im folgenden Beispiel werden alle derzeit im BlockStore gespeicherten Tokens gelöscht:

Java

// Delete all data.
DeleteBytesRequest deleteAllRequest = new DeleteBytesRequest.Builder()
      .setDeleteAll(true)
      .build();
client.deleteBytes(deleteAllRequest)
.addOnSuccessListener(result -> Log.d(TAG, "Any data found and deleted? " + result));

Kotlin

  val deleteAllRequest = DeleteBytesRequest.Builder()
  .setDeleteAll(true)
  .build()
client.deleteBytes(deleteAllRequest)
  .addOnSuccessListener { result: Boolean ->
    Log.d(TAG,
          "Any data found and deleted? $result")
  }

Ende-zu-Ende-Verschlüsselung

Damit die Ende-zu-Ende-Verschlüsselung zur Verfügung gestellt werden kann, muss das Gerät mit Android 9 oder höher und der Nutzer muss eine Displaysperre eingerichtet haben (PIN, Muster oder Passwort) für ihr Gerät. Sie können überprüfen, ob die Verschlüsselung durch Aufrufen von isEndToEndEncryptionAvailable() auf dem Gerät verfügbar sein.

Im folgenden Beispiel sehen Sie, wie Sie prüfen können, ob die Verschlüsselung während Cloud-Sicherung:

client.isEndToEndEncryptionAvailable()
        .addOnSuccessListener { result ->
          Log.d(TAG, "Will Block Store cloud backup be end-to-end encrypted? $result")
        }

Cloud-Sicherung aktivieren

Um die Cloud-Sicherung zu aktivieren, fügen Sie den setShouldBackupToCloud() zu Ihrem StoreBytesData -Objekt enthält. Block Store sichert die gespeicherten Byte regelmäßig in der Cloud, wenn setShouldBackupToCloud() ist auf „true“ gesetzt.

Das folgende Beispiel zeigt, wie die Cloud-Sicherung nur bei Cloud-Sicherung aktiviert wird. ist mit Ende-zu-Ende-Verschlüsselung geschützt:

val client = Blockstore.getClient(this)
val storeBytesDataBuilder = StoreBytesData.Builder()
        .setBytes(/* BYTE_ARRAY */)

client.isEndToEndEncryptionAvailable()
        .addOnSuccessListener { isE2EEAvailable ->
          if (isE2EEAvailable) {
            storeBytesDataBuilder.setShouldBackupToCloud(true)
            Log.d(TAG, "E2EE is available, enable backing up bytes to the cloud.")

            client.storeBytes(storeBytesDataBuilder.build())
                .addOnSuccessListener { result ->
                  Log.d(TAG, "stored: ${result.getBytesStored()}")
                }.addOnFailureListener { e ->
                  Log.e(TAG, “Failed to store bytes”, e)
                }
          } else {
            Log.d(TAG, "E2EE is not available, only store bytes for D2D restore.")
          }
        }

Testanleitung

Verwenden Sie während der Entwicklung die folgenden Methoden, um die Wiederherstellung zu testen fließen.

Deinstallation/Neuinstallation auf demselben Gerät

Wenn der Nutzer Sicherungsdienste aktiviert Diese Einstellung kann unter Einstellungen > Google > Sicherung angezeigt werden. bei der Deinstallation/Neuinstallation der App blieben.

So testen Sie:

  1. BlockStore API in Ihre Test-App einbinden
  2. Verwenden Sie die Test-App, um die BlockStore API zum Speichern Ihrer Daten aufzurufen.
  3. Deinstallieren Sie die Test-App und installieren Sie sie dann auf demselben Gerät neu.
  4. Verwenden Sie die Testanwendung, um die BlockStore API aufzurufen und Ihre Daten abzurufen.
  5. Prüfen, ob die abgerufenen Byte mit denen übereinstimmen, die zuvor gespeichert wurden Deinstallation.

Gerät zu Gerät

In den meisten Fällen muss dazu das Zielgerät auf die Werkseinstellungen zurückgesetzt werden. Sie können Rufen Sie dann den Vorgang für die WLAN-Wiederherstellung unter Android auf. oder Google-Kabelsicherung (für unterstützte Geräte).

Cloud-Wiederherstellung

  1. Binden Sie die Blockstore API in Ihre Test-App ein. Die Test-App muss die an den Play Store gesendet wurden.
  2. Verwenden Sie auf dem Quellgerät die Test-App, um die Blockstore API zum Speichern mit sollteBackUpToCloud auf „true“ gesetzt sein.
  3. Bei O-Geräten und höher können Sie manuell ein Block Store-Cloud-Back-up auslösen: Öffnen Sie Einstellungen > Google > Sicherung auf die Schaltfläche „Jetzt sichern“.
    1. So prüfen Sie, ob die Block Store-Cloud-Sicherung erfolgreich war: <ph type="x-smartling-placeholder">
        </ph>
      1. Nach Abschluss der Sicherung nach Logzeilen mit dem Tag suchen „CloudSyncBpTkSvc“.
      2. Sie sollten Zeilen wie diese sehen: "......, CloudSyncBpTkSvc: sync Ergebnis: SUCCESS, ..., hochgeladene Größe: XXX Bytes ...“
    2. Nach einem Block Store-Cloud-Back-up gibt es eine Wartezeit von 5 Minuten. Innerhalb dieser 5 Minuten wird kein Klick auf die Schaltfläche „Jetzt sichern“ ausgelöst. ein weiteres Block Store-Cloud-Back-up.
  4. Setzen Sie das Zielgerät auf die Werkseinstellungen zurück und führen Sie eine Cloud-Wiederherstellung durch. Auswählen um die Test-App während der Wiederherstellung wiederherzustellen. Weitere Informationen zu Cloud-Wiederherstellungsabläufe finden Sie unter Unterstützte Cloud-Wiederherstellungsabläufe.
  5. Verwenden Sie auf dem Zielgerät die Test-App, um die Blockstore API aufzurufen, um Ihre Daten abzurufen.
  6. Prüfen Sie, ob die abgerufenen Byte mit denen übereinstimmen, die im Quellgerät.

Geräteanforderungen

Ende-zu-Ende-Verschlüsselung

  • Die Ende-zu-Ende-Verschlüsselung wird auf Geräten mit Android 9 (API 29) und höher unterstützt.
  • Auf dem Gerät muss eine Displaysperre mit PIN, Muster oder Passwort eingerichtet sein, damit die Ende-zu-Ende-Verschlüsselung aktiviert ist und die Daten des Nutzers korrekt verschlüsselt werden.

Ablauf der Wiederherstellung von einem Gerät zum Gerät

Für die Wiederherstellung von Gerät zu Gerät benötigen Sie ein Quell- und ein Zielgerät. Das sind die beiden Geräte, auf denen Daten übertragen werden.

Quellgeräte müssen für die Sicherung Android 6 (API 23) oder höher ausführen.

Ausrichtung auf Geräte mit Android 9 (API-Version 29) und höher, um wiederherzustellen

Weitere Informationen zur Wiederherstellung von einem Gerät zum Gerät finden Sie hier.

Ablauf für Cloud-Sicherung und -Wiederherstellung

Für die Sicherung und Wiederherstellung in der Cloud sind ein Quell- und ein Zielgerät erforderlich.

Quellgeräte müssen für die Sicherung Android 6 (API 23) oder höher ausführen.

Zielgeräte werden je nach Anbieter unterstützt. Pixel kann diese Funktion ab Android 9 (API 29) nutzen. Auf allen anderen Geräten muss Android 12 (API 31) oder höher installiert sein.