ผู้ใช้จํานวนมากยังคงจัดการข้อมูลเข้าสู่ระบบของตนเองเมื่อตั้งค่าอุปกรณ์ Android เครื่องใหม่ กระบวนการที่ต้องลงมือทำเองนี้อาจเป็นเรื่องยากและมักส่งผลให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ไม่ดี Block Store API ซึ่งเป็นไลบรารีที่ขับเคลื่อนโดย Google Play Services พยายามแก้ปัญหานี้ด้วยการจัดหาวิธีให้แอปบันทึกข้อมูลเข้าสู่ระบบของผู้ใช้โดยไม่ต้องมีความซับซ้อนหรือความเสี่ยงด้านความปลอดภัยที่เชื่อมโยงกับการบันทึกรหัสผ่านของผู้ใช้
Block Store API ช่วยให้แอปของคุณจัดเก็บข้อมูลที่ดึงข้อมูลมาใช้ภายหลังเพื่อตรวจสอบสิทธิ์ผู้ใช้อีกครั้งในอุปกรณ์เครื่องใหม่ได้ วิธีนี้ช่วยให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ราบรื่นยิ่งขึ้น เนื่องจากผู้ใช้ไม่ต้องเห็นหน้าจอลงชื่อเข้าใช้เมื่อเปิดแอปเป็นครั้งแรกในอุปกรณ์เครื่องใหม่
ประโยชน์ของการใช้ Block Store มีดังนี้
- โซลูชันพื้นที่เก็บข้อมูลเข้าสู่ระบบที่เข้ารหัสสำหรับนักพัฒนาแอป ข้อมูลเข้าสู่ระบบจะได้รับการเข้ารหัสจากต้นทางถึงปลายทางเมื่อเป็นไปได้
- บันทึกโทเค็นแทนชื่อผู้ใช้และรหัสผ่าน
- ลดความซับซ้อนของขั้นตอนการลงชื่อเข้าใช้
- ช่วยให้ผู้ใช้ไม่ต้องจัดการรหัสผ่านที่ซับซ้อน
- Google ยืนยันตัวตนของผู้ใช้
ก่อนเริ่มต้น
ทําตามขั้นตอนในส่วนต่อไปนี้เพื่อเตรียมแอป
กำหนดค่าแอป
ในไฟล์ build.gradle
ระดับโปรเจ็กต์ ให้ใส่ที่เก็บ Maven ของ Google ทั้งในส่วนที่ buildscript
และ allprojects
ดังนี้
buildscript {
repositories {
google()
mavenCentral()
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
เพิ่มทรัพยากร Dependency ของ Google Play Services สำหรับ Block Store API ลงในไฟล์บิลด์ Gradle ของโมดูล ซึ่งโดยทั่วไปคือ app/build.gradle
dependencies {
implementation 'com.google.android.gms:play-services-auth-blockstore:16.4.0'
}
วิธีการทำงาน
Block Store ช่วยให้นักพัฒนาแอปบันทึกและกู้คืนอาร์เรย์ไบต์ได้สูงสุด 16 รายการ ซึ่งจะช่วยให้คุณบันทึกข้อมูลสําคัญเกี่ยวกับเซสชันผู้ใช้ปัจจุบันได้ และมีความยืดหยุ่นในการบันทึกข้อมูลนี้ในลักษณะที่ต้องการ ข้อมูลนี้สามารถเข้ารหัสจากต้นทางถึงปลายทาง และโครงสร้างพื้นฐานที่รองรับ Block Store จะสร้างขึ้นจากโครงสร้างพื้นฐานการสำรองและกู้คืน
คู่มือนี้จะกล่าวถึงกรณีการใช้งานของการเก็บโทเค็นของผู้ใช้ไปยัง Block Store ขั้นตอนต่อไปนี้จะอธิบายวิธีการทำงานของแอปที่ใช้ Block Store
- ในระหว่างขั้นตอนการตรวจสอบสิทธิ์ของแอปหรือเมื่อใดก็ได้หลังจากนั้น คุณสามารถจัดเก็บโทเค็นการตรวจสอบสิทธิ์ของผู้ใช้ไว้ใน Block Store เพื่อดึงข้อมูลในภายหลัง
- ระบบจะจัดเก็บโทเค็นไว้ในเครื่องและสำรองข้อมูลไปยังระบบคลาวด์ได้ด้วย โดยระบบจะเข้ารหัสจากต้นทางถึงปลายทางเมื่อเป็นไปได้
- ระบบจะโอนข้อมูลเมื่อผู้ใช้เริ่มขั้นตอนการกู้คืนในอุปกรณ์เครื่องใหม่
- หากผู้ใช้กู้คืนแอประหว่างขั้นตอนการกู้คืน แอปจะดึงข้อมูลโทเค็นที่บันทึกไว้จาก Block Store ในอุปกรณ์เครื่องใหม่ได้
บันทึกโทเค็น
เมื่อผู้ใช้ลงชื่อเข้าใช้แอป คุณสามารถบันทึกโทเค็นการตรวจสอบสิทธิ์ที่คุณสร้างขึ้นสําหรับผู้ใช้รายนั้นลงใน Block Store คุณสามารถจัดเก็บโทเค็นนี้โดยใช้ค่าคู่คีย์ที่ไม่ซ้ำกันซึ่งมีขนาดสูงสุด 4 KB ต่อรายการ หากต้องการจัดเก็บโทเค็น ให้เรียกใช้ setBytes()
และ setKey()
ในอินสแตนซ์ของ StoreBytesData.Builder
เพื่อจัดเก็บข้อมูลเข้าสู่ระบบของผู้ใช้ไปยังอุปกรณ์ต้นทาง หลังจากบันทึกโทเค็นด้วย Block Store แล้ว ระบบจะเข้ารหัสและจัดเก็บโทเค็นไว้ในอุปกรณ์
ตัวอย่างต่อไปนี้แสดงวิธีบันทึกโทเค็นการตรวจสอบสิทธิ์ลงในอุปกรณ์เครื่อง
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) }
ใช้โทเค็นเริ่มต้น
ข้อมูลที่บันทึกโดยใช้ StoreBytes โดยไม่มีคีย์จะใช้คีย์เริ่มต้น
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) }
กำลังดึงข้อมูลโทเค็น
ต่อมาเมื่อผู้ใช้ทำตามขั้นตอนการกู้คืนในอุปกรณ์เครื่องใหม่ บริการของ Google Play จะยืนยันตัวตนของผู้ใช้ก่อน จากนั้นจึงดึงข้อมูล Block Store ของคุณ ผู้ใช้ได้ตกลงที่จะกู้คืนข้อมูลแอปของคุณแล้วในขั้นตอนการกู้คืน จึงไม่จำเป็นต้องขอความยินยอมเพิ่มเติม เมื่อผู้ใช้เปิดแอป คุณสามารถขอโทเค็นจาก Block Store ได้โดยเรียกใช้ retrieveBytes()
จากนั้นจะใช้โทเค็นที่ดึงมาได้เพื่อลงชื่อเข้าใช้ผู้ใช้ในอุปกรณ์เครื่องใหม่ต่อไปได้
ตัวอย่างต่อไปนี้แสดงวิธีดึงข้อมูลโทเค็นหลายรายการตามคีย์ที่เฉพาะเจาะจง
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) }
ดึงข้อมูลโทเค็นทั้งหมด
ด้านล่างนี้คือตัวอย่างวิธีดึงข้อมูลโทเค็นทั้งหมดที่บันทึกไว้ใน 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) }
ด้านล่างนี้คือตัวอย่างวิธีเรียกข้อมูลคีย์เริ่มต้น
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)
การลบโทเค็น
คุณอาจต้องลบโทเค็นออกจาก BlockStore ด้วยเหตุผลต่อไปนี้
- ผู้ใช้ดำเนินการตามโฟลว์ผู้ใช้ในการออกจากระบบ
- โทเค็นถูกเพิกถอนหรือไม่ถูกต้อง
คุณสามารถระบุโทเค็นที่ต้องลบได้โดยการตั้งค่าอาร์เรย์ของคีย์ที่ต้องลบ ซึ่งคล้ายกับการเรียกข้อมูลโทเค็น
ตัวอย่างต่อไปนี้แสดงวิธีลบคีย์บางรายการ
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)
ลบโทเค็นทั้งหมด
ตัวอย่างต่อไปนี้แสดงวิธีลบโทเค็นทั้งหมดที่บันทึกไว้ใน 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() retrieve bytes, the keyBlockstoreClient.DEFAULT_BYTES_DATA_KEY
can be used in theRetrieveBytesRequest
instance in order to get your saved data
The following example shows how to retrieve the default key.
Java
End-to-end encryption
In order for end-to-end encryption to be made available, the device must be
running Android 9 or higher, and the user must have set a screen lock
(PIN, pattern, or password) for their device. You can verify if encryption will
be available on the device by calling isEndToEndEncryptionAvailable()
.
The following sample shows how to verify if encryption will be available during cloud backup:
client.isEndToEndEncryptionAvailable()
.addOnSuccessListener { result ->
Log.d(TAG, "Will Block Store cloud backup be end-to-end encrypted? $result")
}
เปิดใช้การสำรองข้อมูลในระบบคลาวด์
หากต้องการเปิดใช้การสำรองข้อมูลในระบบคลาวด์ ให้เพิ่มเมธอด setShouldBackupToCloud()
ลงในออบเจ็กต์ StoreBytesData
Block Store จะสำรองข้อมูลไบต์ที่เก็บไว้ในระบบคลาวด์เป็นระยะๆ เมื่อตั้งค่า setShouldBackupToCloud()
เป็น "จริง"
ตัวอย่างต่อไปนี้แสดงวิธีเปิดใช้การสำรองข้อมูลในระบบคลาวด์เฉพาะเมื่อการสำรองข้อมูลในระบบคลาวด์ได้รับการเข้ารหัสจากต้นทางถึงปลายทาง
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.")
}
}
วิธีทดสอบ
ใช้วิธีการต่อไปนี้ในระหว่างการพัฒนาเพื่อทดสอบขั้นตอนการกู้คืน
ถอนการติดตั้ง/ติดตั้งอีกครั้งในอุปกรณ์เดียวกัน
หากผู้ใช้เปิดใช้บริการสํารองข้อมูล (ตรวจสอบได้ที่การตั้งค่า > Google > การสํารองข้อมูล) ระบบจะเก็บข้อมูล Block Store ไว้เมื่อมีการถอนการติดตั้ง/ติดตั้งแอปอีกครั้ง
คุณสามารถทำตามขั้นตอนต่อไปนี้เพื่อทดสอบ
- ผสานรวม Block Store API เข้ากับแอปทดสอบ
- ใช้แอปทดสอบเพื่อเรียกใช้ Block Store API เพื่อจัดเก็บข้อมูล
- ถอนการติดตั้งแอปทดสอบ แล้วติดตั้งแอปอีกครั้งในอุปกรณ์เครื่องเดียวกัน
- ใช้แอปทดสอบเพื่อเรียกใช้ Block Store API เพื่อเรียกข้อมูล
- ยืนยันว่าไบต์ที่ดึงข้อมูลมานั้นเหมือนกับที่เก็บไว้ก่อนการถอนการติดตั้ง
อุปกรณ์ต่ออุปกรณ์
ในกรณีส่วนใหญ่ การดำเนินการนี้จะต้องมีการรีเซ็ตอุปกรณ์เป้าหมายเป็นค่าเริ่มต้น จากนั้นคุณสามารถเข้าสู่ขั้นตอนการกู้คืนแบบไร้สายของ Android หรือการกู้คืนด้วยสายของ Google (สำหรับอุปกรณ์ที่รองรับ)
การกู้คืนข้อมูลในระบบคลาวด์
- ผสานรวม Block Store API เข้ากับแอปทดสอบ และต้องส่งแอปทดสอบไปยัง Play Store
- ในอุปกรณ์ต้นทาง ให้ใช้แอปทดสอบเพื่อเรียกใช้ Block Store API เพื่อจัดเก็บข้อมูล โดยตั้งค่า
shouldBackUpToCloud
เป็นtrue
- สำหรับอุปกรณ์เวอร์ชัน O ขึ้นไป คุณสามารถเรียกใช้การสำรองข้อมูลระบบคลาวด์ของ Block Store ด้วยตนเองได้โดยไปที่การตั้งค่า > Google > การสำรองข้อมูล แล้วคลิกปุ่ม "สำรองข้อมูลเลย"
- หากต้องการตรวจสอบว่าการสำรองข้อมูลในระบบคลาวด์ของ Block Store สำเร็จหรือไม่ ให้ทำดังนี้
- หลังจากสํารองข้อมูลเสร็จแล้ว ให้ค้นหาบรรทัดบันทึกที่มีแท็ก "CloudSyncBpTkSvc"
- คุณควรเห็นบรรทัดข้อมูลอย่างเช่น "......, CloudSyncBpTkSvc: sync result: SUCCESS, ..., uploaded size: XXX bytes ...”
- หลังจากการสำรองข้อมูล Block Store บนระบบคลาวด์แล้ว ระบบจะเข้าสู่ระยะเวลา "พัก" เป็นเวลา 5 นาที ภายใน 5 นาทีดังกล่าว การคลิกปุ่ม "สำรองข้อมูลเลย" จะไม่ทริกเกอร์การสำรองข้อมูลระบบคลาวด์ของ Block Store อีกครั้ง
- หากต้องการตรวจสอบว่าการสำรองข้อมูลในระบบคลาวด์ของ Block Store สำเร็จหรือไม่ ให้ทำดังนี้
- รีเซ็ตอุปกรณ์เป้าหมายเป็นค่าเริ่มต้นและทำตามขั้นตอนการกู้คืนจากระบบคลาวด์ เลือกเพื่อกู้คืนแอปทดสอบในระหว่างขั้นตอนการกู้คืน ดูข้อมูลเพิ่มเติมเกี่ยวกับขั้นตอนการกู้คืนระบบคลาวด์ได้ที่ขั้นตอนการกู้คืนระบบคลาวด์ที่รองรับ
- บนอุปกรณ์เป้าหมาย ให้ใช้แอปทดสอบเพื่อเรียกใช้ Block Store API เพื่อดึงข้อมูล
- ตรวจสอบว่าไบต์ที่ดึงข้อมูลมานั้นเหมือนกับที่เก็บไว้ในอุปกรณ์ต้นทาง
ข้อกำหนดของอุปกรณ์
การเข้ารหัสจากต้นทางถึงปลายทาง
- การเข้ารหัสจากต้นทางถึงปลายทางใช้ได้ในอุปกรณ์ที่ใช้ Android 9 (API 29) ขึ้นไป
- อุปกรณ์ต้องตั้งค่าล็อกหน้าจอด้วย PIN, รูปแบบ หรือรหัสผ่านเพื่อเปิดใช้การเข้ารหัสจากต้นทางถึงปลายทางและเข้ารหัสข้อมูลของผู้ใช้อย่างถูกต้อง
ขั้นตอนการกู้คืนจากอุปกรณ์เครื่องหนึ่งไปยังอีกเครื่องหนึ่ง
การกู้คืนจากอุปกรณ์หนึ่งไปยังอีกอุปกรณ์หนึ่งกำหนดให้คุณต้องมีอุปกรณ์ต้นทางและอุปกรณ์เป้าหมาย อุปกรณ์ 2 เครื่องนี้จะเป็นผู้รับส่งข้อมูล
อุปกรณ์ต้นทางต้องใช้ Android 6 (API 23) ขึ้นไปจึงจะสำรองข้อมูลได้
กำหนดเป้าหมายอุปกรณ์ที่ใช้ Android 9 (API 29) ขึ้นไปเพื่อให้สามารถกู้คืนได้
ดูข้อมูลเพิ่มเติมเกี่ยวกับขั้นตอนการกู้คืนจากอุปกรณ์หนึ่งไปยังอีกอุปกรณ์หนึ่งได้ที่นี่
ขั้นตอนการสํารองและกู้คืนข้อมูลในระบบคลาวด์
การสำรองและกู้คืนข้อมูลในระบบคลาวด์จะต้องมีอุปกรณ์ต้นทางและอุปกรณ์เป้าหมาย
อุปกรณ์ต้นทางต้องใช้ Android 6 (API 23) ขึ้นไปจึงจะสำรองข้อมูลได้
ระบบรองรับอุปกรณ์ Target ตามผู้ให้บริการ อุปกรณ์ Pixel สามารถใช้ฟีเจอร์นี้ได้ตั้งแต่ Android 9 (API 29) ส่วนอุปกรณ์อื่นๆ ทั้งหมดต้องใช้ Android 12 (API 31) ขึ้นไป