Banyak pengguna masih mengelola kredensial mereka sendiri saat menyiapkan Android baru perangkat seluler. Proses manual ini dapat menjadi tantangan dan sering menghasilkan {i>user experience<i}. Block Store API, library yang didukung oleh Google Play layanan penyimpanan, berupaya mengatasi masalah ini dengan menyediakan cara agar aplikasi dapat menyimpan kredensial pengguna tanpa kerumitan atau risiko keamanan yang terkait dengan penyimpanan {i>password<i} pengguna.
Block Store API memungkinkan aplikasi Anda menyimpan data yang dapat disimpan nanti diambil untuk mengautentikasi ulang pengguna pada perangkat baru. Hal ini membantu memberikan gambaran pengalaman yang 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 adalah dienkripsi end-to-end jika memungkinkan.
- Menyimpan token, bukan nama pengguna dan sandi.
- Hilangkan hambatan dari alur login.
- Memudahkan pengguna mengelola sandi yang rumit.
- Google memverifikasi identitas pengguna.
Sebelum memulai
Untuk mempersiapkan aplikasi Anda, selesaikan langkah-langkah di bagian berikut ini.
Mengonfigurasi aplikasi Anda
Di file build.gradle
tingkat project, sertakan Google Maven
repositori di buildscript
dan allprojects
:
buildscript {
repositories {
google()
mavenCentral()
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
Menambahkan layanan Google Play
dependensi untuk Block Store API ke
file build Gradle modul,
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 array hingga 16 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 otentikasi pengguna ke {i> Block Store<i} untuk diambil nanti.
- Token akan disimpan secara lokal dan juga dapat dicadangkan ke {i>cloud<i}, dienkripsi end-to-end jika memungkinkan.
- Data ditransfer saat pengguna memulai alur pemulihan di perangkat baru.
- Jika pengguna memulihkan aplikasi selama alur pemulihan, aplikasi Anda nantinya bisa mengambil token yang disimpan dari Block Store di perangkat baru.
Menyimpan token
Saat pengguna login ke aplikasi, Anda dapat menyimpan token autentikasi yang dibuat 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
di Block Store, token dienkripsi dan disimpan secara lokal di perangkat.
Contoh berikut menunjukkan cara menyimpan token otentikasi 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 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
Kemudian, ketika pengguna masuk
melalui alur pemulihan pada
perangkat, layanan Google Play akan memverifikasi pengguna terlebih dahulu, lalu mengambil Pemblokiran Anda
Menyimpan data. Pengguna telah setuju untuk memulihkan data aplikasi Anda sebagai bagian dari
alur pemulihan, sehingga tidak
ada izin tambahan yang diperlukan. Saat pengguna membuka
aplikasi Anda, Anda dapat meminta token dari
Block Store dengan memanggil
retrieveBytes()
Token yang diambil kemudian dapat digunakan untuk menjaga agar pengguna tetap login di
perangkat seluler.
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 ListrequestedKeys = 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.
Di bawah ini adalah contoh 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) }
Di bawah ini adalah contoh 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
Anda mungkin perlu menghapus token dari BlockStore karena alasan berikut:
- Pengguna melalui alur pengguna logout.
- Token telah dicabut atau tidak valid.
Mirip dengan mengambil token, Anda dapat menentukan token mana yang perlu dihapus dengan menetapkan array kunci yang memerlukan penghapusan.
Berikut adalah contoh untuk 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 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)
Hapus Semua Token
Contoh di bawah ini menghapus semua token yang saat ini disimpan ke BlockStore:
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") }
Enkripsi menyeluruh
Agar enkripsi end-to-end tersedia, perangkat harus
menjalankan Android 9 atau yang lebih tinggi, dan pengguna harus menyetel kunci layar
(PIN, pola, atau sandi) untuk perangkat mereka. 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")
}
Aktifkan pencadangan cloud
Untuk mengaktifkan pencadangan cloud, tambahkan
setShouldBackupToCloud()
metode ke
StoreBytesData
. {i>Block Store<i} akan secara berkala mencadangkan ke {i>cloud <i}byte yang disimpan ketika
setShouldBackupToCloud()
ditetapkan sebagai true (benar).
Contoh berikut menunjukkan cara mengaktifkan pencadangan cloud hanya saat 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 pemulihan {i>flow<i} (alur).
Uninstal/instal ulang perangkat yang sama
Jika pengguna mengaktifkan Layanan pencadangan (dapat diperiksa di Setelan > Google > Pencadangan), data Block Store bertahan selama uninstal/instal ulang aplikasi.
Anda dapat mengikuti langkah-langkah berikut untuk menguji:
- Integrasikan BlockStore API ke aplikasi pengujian Anda.
- Gunakan aplikasi pengujian untuk memanggil BlockStore API guna menyimpan data Anda.
- Uninstal aplikasi pengujian, lalu instal ulang aplikasi Anda di perangkat yang sama.
- Gunakan aplikasi pengujian untuk memanggil BlockStore API guna mengambil data Anda.
- Memverifikasi bahwa byte yang diambil sama dengan byte yang disimpan sebelumnya uninstal.
Perangkat ke perangkat
Biasanya, Anda perlu mereset perangkat target ke setelan pabrik. Anda dapat lalu masuk ke alur pemulihan nirkabel Android atau pemulihan kabel Google (untuk perangkat yang didukung).
Pemulihan cloud
- Integrasikan Blockstore API ke aplikasi pengujian Anda. Aplikasi uji coba harus dikirimkan ke Play Store.
- Di perangkat sumber, gunakan aplikasi pengujian untuk memanggil Blockstore API agar menyimpan data Anda, dengan shouldBackUpToCloud disetel ke true.
- Untuk perangkat O dan yang lebih baru, Anda dapat memicu pencadangan cloud Block Store secara manual:
buka Setelan > Google > Cadangkan, klik tombol "Cadangkan Sekarang".
- Untuk memverifikasi bahwa pencadangan cloud Block Store berhasil, Anda dapat:
- Setelah pencadangan selesai, cari baris log dengan tag “CloudSyncBpTkSvc”.
- Anda akan melihat baris seperti ini: “......, CloudSyncBpTkSvc: sync hasil: SUCCESS, ..., ukuran upload: XXX byte ...”
- Setelah pencadangan cloud Block Store, ada periode "pendinginan" selama 5 menit. Dalam 5 menit tersebut, mengklik tombol "Cadangkan Sekarang" tidak akan terpicu cadangan {i>cloud <i} Block Store lainnya.
- Untuk memverifikasi bahwa pencadangan cloud Block Store berhasil, Anda dapat:
- Reset perangkat target ke setelan pabrik dan ikuti alur pemulihan cloud. Pilih untuk memulihkan aplikasi pengujian selama alur pemulihan. Untuk mengetahui informasi selengkapnya tentang alur pemulihan cloud, lihat Alur pemulihan cloud yang didukung.
- Pada perangkat target, gunakan aplikasi pengujian untuk memanggil Blockstore API agar untuk mengambil data Anda.
- Verifikasi bahwa byte yang diambil sama dengan yang disimpan dalam perangkat sumber.
Persyaratan Perangkat
Enkripsi Menyeluruh
- Enkripsi end-to-end didukung di perangkat yang menjalankan Android 9 (API 29) dan yang lebih baru.
- Perangkat harus menyetel kunci layar dengan PIN, pola, atau sandi agar enkripsi end-to-end dapat diaktifkan dan mengenkripsi data pengguna dengan benar.
Alur Pemulihan Perangkat ke Perangkat
Pemulihan perangkat ke perangkat mengharuskan Anda memiliki perangkat sumber dan perangkat target. Ini akan menjadi dua perangkat yang mentransfer data.
Perangkat Sumber harus menjalankan Android 6 (API 23) dan yang lebih baru agar dapat mencadangkan.
Targetkan perangkat yang menjalankan Android 9 (API 29) dan yang lebih baru agar dapat dipulihkan.
Informasi selengkapnya terkait alur pemulihan perangkat ke perangkat dapat ditemukan di sini.
Alur Pencadangan dan Pemulihan Cloud
Pencadangan dan pemulihan cloud akan memerlukan perangkat sumber dan perangkat target.
Perangkat Sumber harus menjalankan Android 6 (API 23) dan yang lebih baru agar dapat mencadangkan.
Perangkat target didukung berdasarkan vendornya. Perangkat Pixel dapat menggunakan fitur ini dari Android 9 (API 29) dan semua perangkat lain harus menjalankan Android 12 (API 31) atau yang lebih baru.