ผู้ใช้หลายคนยังคงจัดการข้อมูลรับรองของตนเองขณะตั้งค่าอุปกรณ์ Android ใหม่ กระบวนการที่ดําเนินการด้วยตนเองนี้อาจกลายเป็นเรื่องท้าทายและมักทําให้ผู้ใช้ได้รับประสบการณ์ที่ไม่ดี Block Store API ไลบรารีที่ขับเคลื่อนโดยบริการ Google Play จะแก้ปัญหานี้ด้วยวิธีที่จะช่วยให้แอปบันทึกข้อมูลรับรองของผู้ใช้โดยไม่ยุ่งยากหรือมีความเสี่ยงด้านความปลอดภัยในการบันทึกรหัสผ่านของผู้ใช้
Block Store API ช่วยให้แอปจัดเก็บข้อมูลที่จะนําไปใช้เพื่อตรวจสอบสิทธิ์ผู้ใช้อีกครั้งในอุปกรณ์เครื่องใหม่ได้ภายหลัง วิธีนี้ช่วยให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ราบรื่นยิ่งขึ้น เนื่องจากผู้ใช้ไม่จําเป็นต้องเห็นหน้าจอลงชื่อเข้าใช้เมื่อเปิดแอปเป็นครั้งแรกในอุปกรณ์เครื่องใหม่
ประโยชน์ของการใช้ Block Store มีดังนี้
- โซลูชันที่จัดเก็บข้อมูลรับรองที่เข้ารหัสสําหรับนักพัฒนาซอฟต์แวร์ ข้อมูลรับรองจะเข้ารหัส แบบจุดต่อจุดเมื่อเป็นไปได้
- บันทึกโทเค็นแทนชื่อผู้ใช้และรหัสผ่าน
- ขจัดอุปสรรคจากขั้นตอนการลงชื่อเข้าใช้
- ช่วยให้ผู้ใช้ไม่ต้องแบกรับภาระในการจัดการรหัสผ่านที่ซับซ้อน
- Google ยืนยันตัวตนของผู้ใช้
ข้อควรทราบก่อนที่จะเริ่มต้น
ในการเตรียมแอป ให้ทําตามขั้นตอนในหัวข้อต่อไปนี้
กําหนดค่าแอปของคุณ
ในไฟล์ build.gradle
ระดับโปรเจ็กต์ ให้รวมที่เก็บ Maven ของ Google ทั้งในส่วน buildscript
และ allprojects
ดังนี้
buildscript {
repositories {
google()
mavenCentral()
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
เพิ่มการอ้างอิงบริการ Google Play สําหรับ Block Store API ในไฟล์บิวด์แบบ Gradle ของโมดูล ซึ่งโดยทั่วไปคือ app/build.gradle
dependencies {
implementation 'com.google.android.gms:play-services-auth-blockstore:16.2.0'
}
ลักษณะการทำงาน
Block Store ช่วยให้นักพัฒนาซอฟต์แวร์บันทึกและคืนค่าอาร์เรย์สูงสุด 16 ไบต์ วิธีนี้จะช่วยให้คุณบันทึกข้อมูลสําคัญเกี่ยวกับเซสชันผู้ใช้ปัจจุบัน และมีความยืดหยุ่นในการบันทึกข้อมูลนี้ตามที่คุณต้องการ ข้อมูลนี้สามารถเข้ารหัสจากต้นทางถึงปลายทางได้ และโครงสร้างพื้นฐานที่สนับสนุน Block Store สร้างขึ้นบนโครงสร้างพื้นฐานของการสํารองและคืนค่าข้อมูล
คู่มือนี้จะครอบคลุมกรณีการใช้งานเกี่ยวกับการบันทึกโทเค็นของผู้ใช้ลงใน Block Store ขั้นตอนต่อไปนี้สรุปวิธีการทํางานของแอปที่ใช้ Block Store
- ระหว่างขั้นตอนการตรวจสอบสิทธิ์แอป หรือในภายหลัง คุณสามารถจัดเก็บโทเค็นการตรวจสอบสิทธิ์ของผู้ใช้ไปยัง Block Store เพื่อดึงข้อมูลในภายหลังได้
- ระบบจะจัดเก็บโทเค็นไว้ในเครื่องและสามารถสํารองข้อมูลไปยังระบบคลาวด์และเข้ารหัสแบบจุดต่อจุดได้ถ้าเป็นไปได้
- ระบบจะโอนข้อมูลเมื่อผู้ใช้เริ่มกระบวนการคืนค่าในอุปกรณ์ใหม่
- หากผู้ใช้คืนค่าแอปของคุณระหว่างขั้นตอนการกู้คืน แอปจะดึงข้อมูลโทเค็นที่บันทึกไว้จากบล็อกสโตร์บนอุปกรณ์ใหม่ได้
กําลังบันทึกโทเค็น
เมื่อผู้ใช้ลงชื่อเข้าใช้แอป คุณสามารถบันทึกโทเค็นการตรวจสอบสิทธิ์ที่คุณสร้างขึ้นสําหรับผู้ใช้รายนั้นไปยัง Block Store คุณจัดเก็บโทเค็นนี้โดยใช้ค่าคู่คีย์ที่ไม่ซ้ํากันซึ่งมีขนาดได้สูงสุด 4KB ต่อรายการ
หากต้องการจัดเก็บโทเค็น ให้เรียกใช้ setBytes()
และ 'setKey(/android/reference/com/google/android/gms/auth/blockstore/StoreBytesData.Builder.html#setKey(java.lang.String)' ในอินสแตนซ์ของ StoreBytesData.Builder
เพื่อจัดเก็บข้อมูลเข้าสู่ระบบของผู้ใช้ไปยังอุปกรณ์ต้นทาง หลังจากบันทึกโทเค็นด้วย
บล็อกสโตร์แล้ว โทเค็นจะถูกเข้ารหัสและจัดเก็บไว้ในเครื่อง
ตัวอย่างต่อไปนี้แสดงวิธีบันทึกโทเค็นการตรวจสอบสิทธิ์ลงในอุปกรณ์ในระบบ
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 จะยืนยันผู้ใช้ก่อน แล้วจึงเรียกข้อมูลการบล็อกใน 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 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) }
เรียกดูโทเค็นทั้งหมด
ด้านล่างนี้คือตัวอย่างวิธีเรียกดูโทเค็นทั้งหมดที่บันทึกไว้ใน BlockStore
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) }
ด้านล่างนี้คือตัวอย่างวิธีเรียกข้อมูลคีย์เริ่มต้น
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() client.deleteBytes(deleteAllRequest) .addOnSuccessListener { result: Boolean -> Log.d(TAG, "Any data found and deleted? $result") }
การเข้ารหัสจากต้นทางถึงปลายทาง
โดยอุปกรณ์จะต้องใช้ Android 9 ขึ้นไปและผู้ใช้ต้องตั้งค่าการล็อกหน้าจอ (PIN, รูปแบบ หรือรหัสผ่าน) ของอุปกรณ์เพื่อให้การเข้ารหัสแบบจุดต่อจุดพร้อมใช้งาน คุณยืนยันได้ว่าจะมีการเข้ารหัสในอุปกรณ์หรือไม่โดยโทรไปที่ isEndToEndEncryptionAvailable()
ตัวอย่างต่อไปนี้แสดงวิธีตรวจสอบว่าการเข้ารหัสจะพร้อมใช้งานระหว่างการสํารองข้อมูลในระบบคลาวด์หรือไม่
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 > การสํารองข้อมูล) ข้อมูลบล็อกสโตร์จะถูกถอนการติดตั้ง/ติดตั้งแอปอีกครั้ง
คุณสามารถทําตามขั้นตอนต่อไปนี้เพื่อทดสอบ
- ผสานรวม BlockStore API ลงในแอปทดสอบ
- ใช้แอปทดสอบเพื่อเรียก BlockStore API เพื่อเก็บข้อมูล
- ถอนการติดตั้งแอปทดสอบแล้วติดตั้งแอปในอุปกรณ์เดิมอีกครั้ง
- ใช้แอปทดสอบเพื่อเรียก BlockStore API เพื่อเรียกข้อมูล
- ตรวจสอบว่าจํานวนไบต์ที่ดึงมาตรงกับที่เก็บไว้ในก่อนถอนการติดตั้ง
อุปกรณ์ต่ออุปกรณ์
ในกรณีส่วนใหญ่ จะต้องมีการรีเซ็ตอุปกรณ์ปลายทางเป็นค่าเริ่มต้น คุณสามารถป้อน ขั้นตอนการคืนค่า Android แบบไร้สาย หรือคืนค่าสาย Google (สําหรับอุปกรณ์ที่สนับสนุน)
การกู้คืนระบบคลาวด์
- ผสานรวม Blockstore API ลงในแอปทดสอบ แอปทดสอบจําเป็นต้องส่งไปยัง Play Store
- ในอุปกรณ์ต้นทาง ให้ใช้แอปทดสอบเพื่อเรียก API ของ Blockstore เพื่อเก็บข้อมูล โดยตั้งค่า ShoBackUpCloud เป็น "จริง"
- สําหรับอุปกรณ์ O และอุปกรณ์ข้างต้น คุณสามารถทริกเกอร์การสํารองข้อมูลในระบบคลาวด์ของ Store Store ได้ด้วยตนเอง
โดยไปที่การตั้งค่า > Google > การสํารองข้อมูล คลิกปุ่ม “สํารองข้อมูลเลย”
- หากต้องการยืนยันว่าการสํารองข้อมูลระบบคลาวด์ของ Store Store ดําเนินการสําเร็จแล้ว ให้ทําดังนี้
- หลังจากสํารองข้อมูลเรียบร้อยแล้ว ให้ค้นหาบรรทัดของบันทึกที่มีแท็ก “CloudSyncBpTkSvc”
- คุณควรเห็นบรรทัดลักษณะต่อไปนี้ “......, CloudSyncBpTkSvc: sync result: SUCCESS, ..., uploaded size: XXX bytes ...”
- หลังจากสํารองข้อมูลในระบบคลาวด์ของ Store Store แล้ว ระบบจะ “พัก” เป็นเวลา 5 นาที ภายในเวลา 5 นาที การคลิกปุ่ม “สํารองข้อมูลทันที” จะไม่ทําให้เกิด การสํารองข้อมูลในระบบคลาวด์อีกใน Store Store
- หากต้องการยืนยันว่าการสํารองข้อมูลระบบคลาวด์ของ Store Store ดําเนินการสําเร็จแล้ว ให้ทําดังนี้
- รีเซ็ตอุปกรณ์เป้าหมายเป็นค่าเริ่มต้นและทําตามขั้นตอนการกู้คืนระบบคลาวด์ เลือกเพื่อคืนค่าแอปทดสอบระหว่างขั้นตอนการกู้คืน โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับขั้นตอนการกู้คืนในคลาวด์ที่ขั้นตอนการกู้คืนในระบบคลาวด์ที่รองรับ
- ในอุปกรณ์เป้าหมาย ให้ใช้แอปทดสอบเพื่อเรียก Blockstore API เพื่อเรียกข้อมูล
- ยืนยันว่าไบต์ที่ดึงมานั้นเหมือนกับที่เก็บไว้ในอุปกรณ์ต้นทาง
ข้อกําหนดของอุปกรณ์
การเข้ารหัสจากต้นทางถึงปลายทาง
- การเข้ารหัสแบบจุดต่อจุดได้รับการสนับสนุนในอุปกรณ์ที่ใช้ Android 9 (API 29) ขึ้นไป
- อุปกรณ์ต้องล็อกหน้าจอด้วย PIN, รูปแบบ หรือรหัสผ่านเพื่อให้มีการเข้ารหัสจากต้นทางถึงปลายทางและเข้ารหัสข้อมูลของผู้ใช้ได้อย่างถูกต้อง
ขั้นตอนการกู้คืนระหว่างอุปกรณ์
ในการคืนค่าอุปกรณ์ คุณจะต้องมีอุปกรณ์ต้นทางและอุปกรณ์เป้าหมาย ซึ่งก็คืออุปกรณ์ 2 เครื่องที่กําลังโอนข้อมูล
อุปกรณ์ต้นทางต้องใช้ Android 6 (API 23) ขึ้นไปเพื่อสํารองข้อมูล
กําหนดเป้าหมายอุปกรณ์ที่ใช้ Android 9 (API 29) ขึ้นไปเพื่อให้กู้คืนได้
คุณสามารถดูข้อมูลเพิ่มเติมเกี่ยวกับขั้นตอนการคืนค่าอุปกรณ์ได้ที่นี่
ขั้นตอนการสํารองและกู้คืนข้อมูลในระบบคลาวด์
การสํารองและกู้คืนข้อมูลในระบบคลาวด์จะต้องใช้อุปกรณ์ต้นทางและอุปกรณ์เป้าหมาย
อุปกรณ์ต้นทางต้องใช้ Android 6 (API 23) ขึ้นไปเพื่อสํารองข้อมูล
ระบบรองรับอุปกรณ์เป้าหมายตามผู้ให้บริการ อุปกรณ์ Pixel ใช้ฟีเจอร์นี้ได้จาก Android 9 (API 29) และอุปกรณ์อื่นๆ ทั้งหมดต้องใช้ Android 12 (API 31) ขึ้นไป