Banyak pengguna masih mengelola kredensial mereka sendiri saat menyiapkan perangkat baru yang didukung Android. Proses manual ini dapat menjadi sulit dan sering kali mengakibatkan pengalaman pengguna yang buruk. Block Store API, library yang didukung oleh layanan Google Play, berupaya mengatasi masalah ini dengan menyediakan cara bagi aplikasi untuk menyimpan kredensial pengguna tanpa kerumitan atau risiko keamanan yang terkait dengan penyimpanan sandi pengguna.
Block Store API memungkinkan aplikasi Anda menyimpan data yang nantinya dapat diambil untuk mengautentikasi ulang pengguna di perangkat baru. Hal ini membantu memberikan pengalaman yang lebih lancar bagi pengguna, karena mereka tidak perlu melihat layar login saat meluncurkan aplikasi Anda untuk pertama kalinya di perangkat baru.
Manfaat menggunakan Block Store meliputi:
- Solusi penyimpanan kredensial terenkripsi untuk developer. Kredensial dienkripsi end-to-end jika memungkinkan.
- Simpan token, bukan nama pengguna dan sandi.
- Menghilangkan hambatan dari alur login.
- Membebaskan pengguna dari beban mengelola sandi yang rumit.
- Google memverifikasi identitas pengguna.
Sebelum memulai
Untuk mempersiapkan aplikasi Anda, selesaikan langkah-langkah di bagian berikut ini.
Mengonfigurasi aplikasi Anda
Dalam file build.gradle level project, sertakan repositori Maven Google di bagian buildscript dan allprojects:
buildscript {
repositories {
google()
mavenCentral()
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
Tambahkan dependensi layanan Google Play untuk Block Store API
ke file build Gradle modul Anda, yang biasanya adalah app/build.gradle:
dependencies {
implementation 'com.google.android.gms:play-services-auth-blockstore:16.4.0'
}
Cara kerjanya
Block Store memungkinkan developer menyimpan dan memulihkan hingga 16 array byte. Hal ini memungkinkan Anda menyimpan informasi penting terkait sesi pengguna saat ini dan menawarkan fleksibilitas untuk menyimpan informasi ini sesuai keinginan Anda. Data ini dapat dienkripsi end-to-end dan infrastruktur yang mendukung Block Store dibangun di atas infrastruktur Pencadangan dan Pemulihan.
Panduan ini akan membahas kasus penggunaan penyimpanan token pengguna ke Block Store. Langkah-langkah berikut menguraikan cara kerja aplikasi yang menggunakan Block Store:
- Selama alur autentikasi aplikasi, atau kapan saja setelahnya, Anda dapat menyimpan token autentikasi pengguna ke Block Store untuk diambil nanti.
- Token akan disimpan secara lokal dan juga dapat dicadangkan ke cloud, dienkripsi end-to-end jika memungkinkan.
- Data ditransfer saat pengguna memulai alur pemulihan di perangkat baru.
- Jika pengguna memulihkan aplikasi Anda selama alur pemulihan, aplikasi Anda dapat mengambil token yang disimpan dari Block Store di perangkat baru.
Menyimpan token
Saat pengguna login ke aplikasi, Anda dapat menyimpan token autentikasi yang Anda
buat untuk pengguna tersebut ke Block Store. Anda dapat menyimpan token ini menggunakan nilai pasangan kunci unik yang memiliki maksimum 4 kb per entri. Untuk menyimpan token, panggil
setBytes() dan setKey() pada instance
StoreBytesData.Builder untuk menyimpan kredensial pengguna ke perangkat
sumber. Setelah Anda menyimpan token dengan Block Store, token akan dienkripsi dan
disimpan secara lokal di perangkat.
Contoh berikut menunjukkan cara menyimpan token autentikasi ke perangkat lokal:
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)
}
Gunakan token default
Data yang disimpan menggunakan StoreBytes tanpa kunci akan menggunakan kunci default
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)
}
Mengambil token
Nantinya, saat pengguna melalui alur pemulihan di perangkat baru, layanan Google Play
akan memverifikasi pengguna terlebih dahulu, lalu mengambil data Block Store Anda. Pengguna
telah setuju untuk memulihkan data aplikasi Anda sebagai bagian dari alur pemulihan, sehingga tidak diperlukan
izin tambahan. Saat pengguna membuka aplikasi, Anda dapat meminta
token dari Block Store dengan memanggil retrieveBytes(). Token yang diambil
kemudian dapat digunakan untuk membuat pengguna tetap login di perangkat baru.
Contoh berikut menunjukkan cara mengambil beberapa token berdasarkan kunci tertentu.
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<String> requestedKeys = Arrays.asList(key1, key2, key3); // Add keys to array
RetrieveBytesRequest retrieveRequest = new RetrieveBytesRequest.Builder()
.setKeys(requestedKeys)
.build();
client.retrieveBytes(retrieveRequest)
.addOnSuccessListener(
result -> {
Map<String, BlockstoreData> blockstoreDataMap = result.getBlockstoreDataMap();
for (Map.Entry<String, BlockstoreData> 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)
}
Mengambil semua token.
Contoh berikut menunjukkan cara mengambil semua token yang disimpan ke BlockStore.
Java
BlockstoreClient client = Blockstore.getClient(this)
// Retrieve all data.
RetrieveBytesRequest retrieveRequest = new RetrieveBytesRequest.Builder()
.setRetrieveAll(true)
.build();
client.retrieveBytes(retrieveRequest)
.addOnSuccessListener(
result -> {
Map<String, BlockstoreData> blockstoreDataMap = result.getBlockstoreDataMap();
for (Map.Entry<String, BlockstoreData> 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)
}
Contoh berikut menunjukkan cara mengambil kunci default.
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)
Menghapus token
Menghapus token dari BlockStore mungkin diperlukan karena alasan berikut:
- Pengguna melalui alur pengguna logout.
- Token telah dicabut atau tidak valid.
Sama seperti mengambil token, Anda dapat menentukan token mana yang perlu dihapus dengan menetapkan array kunci yang memerlukan penghapusan.
Contoh berikut menunjukkan cara menghapus kunci tertentu:
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<String> 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)
Hapus Semua Token
Contoh berikut menunjukkan cara menghapus semua token yang disimpan ke Block Store:
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
// Delete all data.
val deleteAllRequest = DeleteBytesRequest.Builder()
.setDeleteAll(true)
.build()
client.deleteBytes(deleteAllRequest)
.addOnSuccessListener { result -> Log.d(TAG, "Any data found and deleted? $result") }
Enkripsi end-to-end
Agar enkripsi end-to-end tersedia, perangkat harus
menjalankan Android 9 atau yang lebih baru, dan pengguna harus telah menetapkan kunci layar
(PIN, pola, atau sandi) untuk perangkatnya. Anda dapat memverifikasi apakah enkripsi akan
tersedia di perangkat dengan memanggil isEndToEndEncryptionAvailable().
Contoh berikut menunjukkan cara memverifikasi apakah enkripsi akan tersedia selama pencadangan cloud:
client.isEndToEndEncryptionAvailable()
.addOnSuccessListener { result ->
Log.d(TAG, "Will Block Store cloud backup be end-to-end encrypted? $result")
}
Mengaktifkan pencadangan cloud
Untuk mengaktifkan pencadangan cloud, tambahkan metode setShouldBackupToCloud() ke objek
StoreBytesData Anda. Block Store akan mencadangkan byte yang disimpan ke cloud secara berkala jika setShouldBackupToCloud() ditetapkan sebagai benar (true).
Contoh berikut menunjukkan cara mengaktifkan pencadangan cloud hanya jika pencadangan cloud dienkripsi end-to-end:
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.")
}
}
Cara menguji
Gunakan metode berikut selama pengembangan untuk menguji alur pemulihan.
Uninstal dan instal ulang di perangkat yang sama
Jika pengguna mengaktifkan layanan Pencadangan (dapat diperiksa di Setelan > Google > Pencadangan), data Block Store akan tetap ada saat aplikasi di-uninstal dan diinstal ulang.
Anda dapat mengikuti langkah-langkah berikut untuk menguji:
- Integrasikan Block Store API ke aplikasi pengujian Anda.
- Gunakan aplikasi pengujian untuk memanggil Block Store API guna menyimpan data Anda.
- Uninstal aplikasi pengujian, lalu instal ulang aplikasi di perangkat yang sama.
- Gunakan aplikasi pengujian untuk memanggil Block Store API guna mengambil data Anda.
- Pastikan byte yang diambil sama dengan yang disimpan sebelum uninstal.
Perangkat ke perangkat
Dalam sebagian besar kasus, tindakan ini akan memerlukan reset ke setelan pabrik pada perangkat target. Anda kemudian dapat memasuki alur pemulihan nirkabel Android atau pemulihan kabel Google (untuk perangkat yang didukung).
Pemulihan cloud
- Integrasikan Block Store API ke aplikasi pengujian Anda. Aplikasi pengujian harus dikirim ke Google Play Store.
- Di perangkat sumber, gunakan aplikasi pengujian untuk memanggil Block Store API guna menyimpan
data Anda, dengan
shouldBackUpToCloudditetapkan ketrue. - Di perangkat yang menjalankan Android 8.0 (level API 26) atau yang lebih baru, Anda dapat memicu
pencadangan cloud Block Store secara manual: buka Setelan > Google > Pencadangan,
klik tombol "Cadangkan Sekarang".
- Untuk memverifikasi bahwa pencadangan cloud Block Store berhasil, Anda dapat:
- Setelah pencadangan selesai, telusuri baris log dengan tag
[CloudSyncBackupTaskService]. - Anda akan melihat baris seperti ini:
..., [CloudSyncBackupTaskService] sync result: SUCCESS,..., uploaded size: [size] bytes ...
- Setelah pencadangan selesai, telusuri baris log dengan tag
- Setelah pencadangan cloud Block Store, ada periode "cooldown" selama 5 menit. Dalam waktu 5 menit tersebut, mengklik tombol "Cadangkan Sekarang" tidak akan memicu pencadangan cloud Block Store lainnya.
- Untuk memverifikasi bahwa pencadangan cloud Block Store berhasil, Anda dapat:
- Reset perangkat target ke setelan pabrik dan lakukan alur pemulihan cloud. Pilih untuk memulihkan aplikasi pengujian Anda selama alur pemulihan. Untuk mengetahui informasi selengkapnya tentang alur pemulihan cloud, lihat Alur pemulihan cloud yang didukung.
- Di perangkat target, gunakan aplikasi pengujian untuk memanggil Block Store API guna mengambil data Anda.
- Pastikan byte yang diambil sama dengan yang disimpan di perangkat sumber.
Persyaratan Perangkat
Tinjau persyaratan berikut untuk perangkat yang berpartisipasi dalam operasi Block Store.
Enkripsi End-to-End
- Enkripsi End to End didukung di perangkat yang menjalankan Android 9 (API 29) atau yang lebih baru.
- Perangkat harus memiliki kunci layar yang disetel dengan PIN, pola, atau sandi agar enkripsi end-to-end dapat diaktifkan dan mengenkripsi data pengguna dengan benar.
Alur Pemulihan Antar-Perangkat
Pemulihan dari perangkat ke perangkat akan mengharuskan Anda memiliki perangkat sumber dan perangkat target. Kedua perangkat ini akan mentransfer data.
Perangkat sumber harus menjalankan Android 6 (API 23) atau yang lebih baru untuk melakukan pencadangan.
Targetkan perangkat yang menjalankan Android 9 (API 29) atau yang lebih baru agar memiliki kemampuan untuk memulihkan.
Untuk mengetahui informasi selengkapnya tentang alur pemulihan dari perangkat ke perangkat, lihat Alur pemulihan dari perangkat ke perangkat yang didukung.
Alur Pencadangan dan Pemulihan Cloud
Pencadangan dan pemulihan cloud akan memerlukan perangkat sumber dan perangkat target.
Perangkat sumber harus menjalankan Android 6 (API 23) atau yang lebih baru untuk melakukan pencadangan.
Perangkat target didukung berdasarkan vendornya. Perangkat Pixel dapat menggunakan fitur ini dari Android 9 (API 29) dan semua perangkat lainnya harus menjalankan Android 12 (API 31) atau yang lebih baru.