Viele Nutzer verwalten weiterhin ihre eigenen Anmeldedaten beim Einrichten eines neuen Android-Geräts. Dieser manuelle Prozess kann eine Herausforderung darstellen und oft die Nutzerfreundlichkeit beeinträchtigen. Die Block Store API, eine Bibliothek mit Google Play-Diensten, bietet eine Lösung, mit der Nutzer Anmeldedaten speichern können, ohne dabei mit der Komplexität oder dem Sicherheitsrisiko verbunden zu sein, das mit dem Speichern von Nutzerpasswörtern verbunden ist.
Mit der Block Store API können Sie Daten in Ihrer App speichern, um sie später auf einem neuen Gerät noch einmal zu authentifizieren. Dadurch wird die Nutzung reibungsloser, da Nutzer beim erstmaligen Starten der App auf dem neuen Gerät keinen Anmeldebildschirm sehen müssen.
Zu den Vorteilen von Block Store gehören:
- Verschlüsselte Anmeldedatenspeicher-Lösung für Entwickler Anmeldedaten werden nach Möglichkeit mit Ende-zu-Ende-Verschlüsselung geschützt.
- Tokens anstelle von Nutzernamen und Passwörtern speichern
- Beseitigen Sie Probleme bei der Anmeldung.
- Nutzer müssen sich nicht mehr um die Verwaltung komplexer Passwörter kümmern.
- Google überprüft die Identität des Nutzers.
Hinweis
Führen Sie die Schritte in den folgenden Abschnitten aus, um Ihre App vorzubereiten.
Eigene Anwendung konfigurieren
Fügen Sie in der Datei build.gradle
auf Projektebene das Maven-Repository von Google in die Abschnitte buildscript
und allprojects
ein:
buildscript {
repositories {
google()
mavenCentral()
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
Fügen Sie die Google Play-Dienste-Abhängigkeit für die Block Store API der Gradle-Build-Datei Ihres Moduls hinzu, die in der Regel app/build.gradle
ist:
dependencies {
implementation 'com.google.android.gms:play-services-auth-blockstore:16.2.0'
}
Funktionsweise
Mit dem Block Store können Entwickler bis zu 16-Byte-Arrays speichern und wiederherstellen. Dadurch können Sie wichtige Informationen über die aktuelle Nutzersitzung speichern und diese Informationen beliebig speichern. Diese Daten können Ende-zu-Ende-verschlüsselt sein und die Infrastruktur, die Block Store unterstützt, basiert auf der Infrastruktur für Sicherung und Wiederherstellung.
In diesem Leitfaden erfahren Sie, wie Sie das Token eines Nutzers im Block Store speichern. In den folgenden Schritten wird beschrieben, wie eine App, die den Block Store verwendet, funktioniert:
- Während der Authentifizierung Ihrer Anwendung oder danach können Sie das Authentifizierungstoken des Nutzers zum späteren Abrufen im Block Store speichern.
- Das Token wird lokal gespeichert und kann nach Möglichkeit mit Ende-zu-Ende-Verschlüsselung in der Cloud gesichert werden.
- Die Daten werden übertragen, wenn der Nutzer den Wiederherstellungsprozess auf einem neuen Gerät initiiert.
- Wenn der Nutzer Ihre App während des Wiederherstellungsprozesses wiederherstellt, kann Ihre Anwendung das gespeicherte Token aus dem Block Store auf dem neuen Gerät abrufen.
Token speichern
Wenn sich ein Nutzer in Ihrer App anmeldet, können Sie das generierte Authentifizierungstoken im Block Store speichern. Sie können dieses Token mit einem eindeutigen Schlüsselpaarwert speichern, der pro Eintrag maximal 4 KB groß ist.
Rufen Sie zum Speichern des Tokens setBytes()
und 'setKey(/android/reference/com/google/android/gms/auth/blockstore/StoreBytesData.Builder.html#setKey(java.lang.String)' auf einer Instanz von StoreBytesData.Builder
auf, um die Anmeldedaten des Nutzers auf dem Quellgerät zu speichern. Nachdem Sie das Token mit Block Store gespeichert haben, wird es verschlüsselt und lokal auf dem Gerät gespeichert.
Das folgende Beispiel zeigt, wie das Authentifizierungstoken auf dem lokalen Gerät gespeichert wird:
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
Mit StoreBytes ohne Schlüssel gespeicherte Daten 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
Wenn ein Nutzer den Wiederherstellungsvorgang später auf einem neuen Gerät durchläuft, wird er von den Google Play-Diensten bestätigt. Anschließend werden die Block Store-Daten abgerufen. Der Nutzer hat im Rahmen der Wiederherstellung bereits zugestimmt, dass Ihre App-Daten wiederhergestellt werden. Daher sind keine zusätzlichen Einwilligungen erforderlich. Wenn der Nutzer die Anwendung öffnet, können Sie durch Aufrufen von retrieveBytes()
ein Token aus dem Block Store anfordern.
Das abgerufene Token kann dann verwendet werden, damit der Nutzer auf dem neuen Gerät angemeldet bleibt.
Im folgenden Beispiel wird gezeigt, 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 ListrequestedKeys = 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.
Das folgende Beispiel zeigt, wie Sie alle im BlockStore gespeicherten Tokens abrufen.
Java
BlockstoreClient client = Blockstore.getClient(this) // Retrieve all data. RetrieveBytesRequest retrieveRequest = new RetrieveBytesRequest.Builder() .setRetrieveAll(true) .build(); client.retrieveBytes(retrieveRequest) .addOnSuccessListener( result -> { MapblockstoreDataMap = 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 folgenden Gründen erforderlich sein:
- Nutzer durchläuft Abmeldungsvorgang.
- Das Token wurde widerrufen oder ist ungültig.
Ähnlich wie beim Abrufen von Tokens können Sie festlegen, welche Tokens gelöscht werden sollen, indem Sie ein Array mit Schlüsseln festlegen, die gelöscht werden sollen.
Unten sehen Sie ein Beispiel zum 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 ListrequestedKeys = 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 steht, muss auf dem Gerät Android 9 oder höher installiert sein und der Nutzer muss eine Displaysperre (PIN, Muster oder Passwort) für sein Gerät eingerichtet haben. Sie können prüfen, ob die Verschlüsselung auf dem Gerät verfügbar ist, indem Sie isEndToEndEncryptionAvailable()
aufrufen.
Das folgende Beispiel zeigt, wie Sie prüfen können, ob die Verschlüsselung während der Cloud-Sicherung verfügbar ist:
client.isEndToEndEncryptionAvailable()
.addOnSuccessListener { result ->
Log.d(TAG, "Will Block Store cloud backup be end-to-end encrypted? $result")
}
Cloud-Sicherung aktivieren
Fügen Sie Ihrem StoreBytesData
-Objekt die Methode setShouldBackupToCloud()
hinzu, um die Cloud-Sicherung zu aktivieren. Block Store sichert regelmäßig Sicherungen in der Cloud, wenn setShouldBackupToCloud()
als „true“ festgelegt ist.
Im folgenden Beispiel wird gezeigt, wie Sie die Cloud-Sicherung nur aktivieren, wenn sie mit Ende-zu-Ende-Verschlüsselung geschützt ist:
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.")
}
}
Tests durchführen
Verwenden Sie während der Entwicklung die folgenden Methoden, um die Wiederherstellungsflüsse zu testen.
Deinstallation/Neuinstallation desselben Geräts
Wenn der Nutzer Sicherungsdienste aktiviert (kann unter Einstellungen > Google > Sicherung geprüft werden), werden Block Store-Daten für die Deinstallation/Neuinstallation der App beibehalten.
Gehen Sie dazu so vor:
- Binden Sie die BlockStore API in Ihre Test-App ein.
- Verwenden Sie die Test-App, um die BlockStore API aufzurufen und Ihre Daten zu speichern.
- Deinstallieren Sie die Test-App und installieren Sie sie dann auf demselben Gerät neu.
- Verwenden Sie die Test-App, um die BlockStore API aufzurufen und Ihre Daten abzurufen.
- Prüfen Sie, ob die abgerufenen Byte mit denen vor der Deinstallation übereinstimmen.
Gerät für Gerät
In den meisten Fällen muss das Zielgerät auf die Werkseinstellungen zurückgesetzt werden. Anschließend kannst du den Vorgang für die kabellose Wiederherstellung unter Android oder die Google-Kabelwiederherstellung für unterstützte Geräte starten.
Cloud-Wiederherstellung
- Binden Sie die Blockstore API in Ihre Test-App ein. Die Test-App muss an den Play Store gesendet werden.
- Verwenden Sie auf dem Quellgerät die Test-App, um die Blockstore API aufzurufen, um Ihre Daten zu speichern, wobei shouldBackUpToCloud auf "true" gesetzt sein sollte.
- Auf Geräten mit O und höher können Sie eine Block Store-Cloud-Sicherung manuell auslösen: Rufen Sie Einstellungen > Google > Sichern auf und klicken Sie auf die Schaltfläche "Jetzt sichern".
- So prüfen Sie, ob die Blockspeicher-Cloud-Sicherung erfolgreich war:
- Suchen Sie nach Abschluss der Sicherung nach Logzeilen mit dem Tag „CloudSyncBpTkSvc“.
- Sie sollten die folgenden Zeilen sehen: „..., CloudSyncBpTkSvc: sync result: SUCCESS, ..., uploaded size: XXX bytes ...”
- Nach einer Block-Store-Cloud-Sicherung gibt es eine 5-minütige Abkühlzeit. Innerhalb dieser 5 Minuten wird durch Klicken auf die Schaltfläche „Jetzt sichern“ keine weitere Block Store-Cloud-Sicherung ausgelöst.
- So prüfen Sie, ob die Blockspeicher-Cloud-Sicherung erfolgreich war:
- Setzen Sie das Zielgerät auf die Werkseinstellungen zurück und durchlaufen Sie einen Wiederherstellungsprozess für die Cloud. Wählen Sie diese Option aus, um Ihre Testanwendung während des Wiederherstellungsprozesses wiederherzustellen. Weitere Informationen zu Abläufen für die Cloud-Wiederherstellung finden Sie unter Unterstützte Abläufe für die Cloud-Wiederherstellung.
- Verwenden Sie auf dem Zielgerät die Test-App, um die Blockstore API aufzurufen, um Ihre Daten abzurufen.
- Prüfen Sie, ob die abgerufenen Byte mit den auf dem Quellgerät gespeicherten Byte übereinstimmen.
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 einer PIN, einem Muster oder einem Passwort eingerichtet sein, damit die Ende-zu-Ende-Verschlüsselung aktiviert und die Daten des Nutzers korrekt verschlüsselt werden.
Ablauf zur Wiederherstellung von Gerät zu Gerät
Für die Wiederherstellung zwischen Geräten benötigen Sie ein Quellgerät und ein Zielgerät. Das sind die beiden Geräte, die Daten übertragen.
Für Quellgeräte muss Android 6 (API 23) oder höher installiert sein.
Richten Sie Geräte mit Android 9 (API 29) oder höher aus, damit sie wiederhergestellt werden können.
Weitere Informationen zur Wiederherstellung von Gerät zu Gerät finden Sie hier.
Ablauf für die Sicherung und Wiederherstellung in der Cloud
Für das Sichern und Wiederherstellen in der Cloud sind ein Quellgerät und ein Zielgerät erforderlich.
Für Quellgeräte muss Android 6 (API 23) oder höher installiert sein.
Zielgeräte werden je nach Anbieter unterstützt. Pixel kann diese Funktion ab Android 9 (API 29) nutzen. Alle anderen Geräte müssen Android 12 (API 31) oder höher ausführen.