Zablokuj sklep

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

Wielu użytkowników nadal używa własnych danych logowania podczas konfigurowania nowego urządzenia z Androidem. Ręczne działanie może stać się trudnym zadaniem, które często ogranicza wygodę użytkowników. Biblioteka Block Store API, która korzysta z Usług Google Play, pomaga rozwiązać ten problem, umożliwiając aplikacjom zapisywanie danych logowania użytkowników bez złożoności i bezpieczeństwa związanego z ich zapisywaniem.

Interfejs Block Store API umożliwia Twojej aplikacji przechowywanie danych, które będzie można później pobrać na potrzeby ponownego uwierzytelnienia użytkowników na nowym urządzeniu. Zwiększa to wygodę użytkowników, ponieważ gdy uruchamiają aplikację po raz pierwszy na nowym urządzeniu, nie muszą korzystać z ekranu logowania.

Zalety korzystania z blokady:

  • Rozwiązanie do przechowywania zaszyfrowanych danych logowania dla deweloperów. Dane logowania są w pełni szyfrowane.
  • Zapisz tokeny zamiast nazw użytkowników i haseł.
  • Ogranicz przeszkody na drodze do logowania.
  • Pozwól użytkownikom uniknąć konieczności zarządzania złożonymi hasłami.
  • Google weryfikuje tożsamość użytkownika.

Zanim zaczniesz

Aby przygotować aplikację, wykonaj czynności opisane w kolejnych sekcjach.

Konfiguracja aplikacji

W pliku build.gradle na poziomie projektu uwzględnij repozytorium Google Maven w sekcjach buildscript i allprojects:

buildscript {
  repositories {
    google()
    mavenCentral()
  }
}

allprojects {
  repositories {
    google()
    mavenCentral()
  }
}

Dodaj zależność interfejsu API Store Google Play od interfejsu Block Store API do pliku kompilacji Gradle modułu, który zazwyczaj jest app/build.gradle:

dependencies {
  implementation 'com.google.android.gms:play-services-auth-blockstore:16.2.0'
}

Jak to działa

Blokada sklepu pozwala deweloperom zapisywać i przywracać macierze o rozmiarze do 16 bajtów. W ten sposób możesz zapisać ważne informacje o bieżącej sesji użytkownika i zapisywać je w dowolny sposób. Te dane mogą być w pełni szyfrowane, a infrastruktura obsługująca Blokadę jest oparta na infrastrukturze tworzenia i przywracania kopii zapasowych.

W tym przewodniku opisaliśmy sposób zapisywania tokena użytkownika w Block Store. Oto jak działają aplikacje korzystające z Google Store:

  1. Podczas uwierzytelniania aplikacji lub w dowolnym późniejszym momencie możesz zapisać token uwierzytelniający użytkownika w Google Store i zablokować go na później do pobrania.
  2. Token będzie przechowywany lokalnie, a kopie zapasowe można też tworzyć w chmurze, gdy tylko będzie to w pełni zaszyfrowane.
  3. Dane są przenoszone, gdy użytkownik zainicjuje proces przywracania na nowym urządzeniu.
  4. Jeśli w trakcie procesu przywracania użytkownik przywróci Twoją aplikację, będzie ona mogła pobrać zapisany token z Block Store na nowym urządzeniu.

Zapisuję token

Gdy użytkownik zaloguje się w Twojej aplikacji, możesz zapisać token uwierzytelniania wygenerowany dla tego użytkownika w celu zablokowania sklepu. Token można zapisać przy użyciu unikalnej wartości pary kluczy, która ma maksymalnie 4 KB na wpis. Aby zapisać token, wywołaj metody setBytes() i 'setKey(/android/reference/com/google/android/gms/auth/blockstore/StoreBytesData.Builder.html#setKey(java.lang.String)' w instancji , aby zapisać dane logowania użytkownika na urządzeniu źródłowym. Po zapisaniu tokena w Block Store jest on szyfrowany i przechowywany lokalnie na urządzeniu.

Poniższy przykład pokazuje, jak zapisać token uwierzytelniania na urządzeniu lokalnym:

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)
    }

Użyj tokena domyślnego

Dane zapisywane przy użyciu StoreBytes bez klucza używają domyślnego klucza 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)
    }

Odzyskiwanie tokena

Później, gdy użytkownik wykona procedurę przywracania na nowym urządzeniu, Usługi Google Play najpierw je zweryfikują, a potem pobiorą dane z Google Store. W ramach procesu przywracania użytkownik zgodził się już na przywrócenie danych aplikacji, więc nie jest wymagana dodatkowa zgoda. Gdy użytkownik otworzy Twoją aplikację, możesz poprosić o token z Block Store, wywołując metodę retrieveBytes(). Pobrany token będzie mógł posłużyć do utrzymywania użytkownika zalogowanego na nowym urządzeniu.

Poniższy przykład pokazuje, jak pobrać wiele tokenów na podstawie konkretnych kluczy.

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 requestedKeys = 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)
  }

Pobieram wszystkie tokeny.

Poniżej znajdziesz przykład pobierania wszystkich tokenów zapisanych w BlockStore.

Java

BlockstoreClient client = Blockstore.getClient(this)

// Retrieve all data.
RetrieveBytesRequest retrieveRequest = new RetrieveBytesRequest.Builder()
    .setRetrieveAll(true)
    .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)

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)
  }

Poniżej znajdziesz przykład pobierania klucza domyślnego.

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)

Usuwam tokeny

Usunięcie tokenów z BlockStore może być wymagane z tych powodów:

  • Użytkownik przechodzi przez proces wylogowania.
  • Token został unieważniony lub jest nieprawidłowy.

Podobnie jak w przypadku pobierania tokenów możesz określić, które tokeny wymagają usunięcia, ustawiając tablicę kluczy do usunięcia.

Poniżej znajduje się przykład usuwania niektórych kluczy.

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 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)

Usuń wszystkie tokeny

Przykład poniżej powoduje usunięcie wszystkich tokenów zapisanych obecnie w 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")
  }

Pełne szyfrowanie

Aby pełne szyfrowanie było dostępne, na urządzeniu musi być zainstalowany Android 9 lub nowszy, a użytkownik musi ustawić na urządzeniu blokadę ekranu (kod PIN, wzór lub hasło). Aby sprawdzić, czy szyfrowanie jest dostępne na urządzeniu, wywołaj metodę isEndToEndEncryptionAvailable().

Poniższy przykład pokazuje, jak sprawdzić, czy szyfrowanie będzie dostępne podczas tworzenia kopii zapasowej w chmurze:

client.isEndToEndEncryptionAvailable()
        .addOnSuccessListener { result ->
          Log.d(TAG, "Will Block Store cloud backup be end-to-end encrypted? $result")
        }

Włącz kopię zapasową w chmurze

Aby włączyć kopię zapasową w chmurze, dodaj metodę setShouldBackupToCloud() do obiektu StoreBytesData. Gdy zasada setShouldBackupToCloud() ma wartość Prawda, okresowo jest tworzona kopia zapasowa w chmurze przechowywana w chmurze.

Poniższy przykład pokazuje, jak włączyć kopię zapasową w chmurze tylko wtedy, gdy kopia zapasowa w chmurze jest w pełni szyfrowana:

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.")
          }
        }

Testowanie

Aby przetestować procesy przywracania, podczas programowania użyj tych metod.

Odinstalowanie/ponowne zainstalowanie tego samego urządzenia

Jeśli użytkownik włączy usługi kopii zapasowej (możesz to sprawdzić w sekcji Ustawienia > Google > Kopia zapasowa), dane o blokowaniu sklepu są trwałe w sekcji odinstalowania i ponownej instalacji aplikacji.

Aby to sprawdzić:

  1. Zintegruj Blokadę API z aplikacją testową.
  2. Użyj aplikacji testowej, aby wywołać interfejs BlockStore API na potrzeby przechowywania danych.
  3. Odinstaluj aplikację testową i zainstaluj ją jeszcze raz na tym samym urządzeniu.
  4. Aby pobrać swoje dane, użyj aplikacji testowej do wywołania interfejsu BlockStore API.
  5. Sprawdź, czy pobrane bajty są takie same jak te zapisane przed odinstalowaniem.

Z urządzenia na urządzenie

W większości przypadków wymaga to przywrócenia urządzenia docelowego do ustawień fabrycznych. Możesz wpisać procedurę przywracania bezprzewodowego w Androidzie lub przywrócenie kabla Google (w przypadku obsługiwanych urządzeń).

Przywracanie w chmurze

  1. Zintegruj aplikację Blockstore API z aplikacją testową. Aplikacja testowa musi zostać przesłana do Sklepu Play.
  2. Na urządzeniu źródłowym skorzystaj z aplikacji testowej, aby wywołać interfejs Blockstore API na potrzeby przechowywania danych. Parametr trueBackUpToCloud ma wartość „true”.
  3. Na urządzeniach z O i nowszymi ustawieniami możesz ręcznie uruchamiać tworzenie kopii zapasowej w chmurze. Aby to zrobić, kliknij Ustawienia > Google > Kopia zapasowa i kliknij przycisk „Utwórz kopię zapasową”.
    1. Aby sprawdzić, czy tworzenie kopii zapasowej w chmurze w Store zostało ukończone, możesz:
      1. Po utworzeniu kopii zapasowej wyszukaj wiersze logu z tagiem „CloudSyncBpTkSvc”.
      2. Powinny pojawić się następujące wiersze: „......, CloudSyncBpTkSvc: wynik synchronizacji: SUCCESS, ..., przesłany rozmiar: XXX bajtów ...”
    2. Po utworzeniu kopii zapasowej w chmurze sklepu następuje 5-minutowy okres oczekiwania. W ciągu 5 minut kliknięcie przycisku „Utwórz kopię zapasową teraz” nie spowoduje uruchomienia kolejnej kopii zapasowej chmury sklepu.
  4. Przywróć ustawienia fabryczne na urządzeniu docelowym i wykonaj procedurę przywracania w chmurze. Wybierz, aby przywrócić aplikację testową w trakcie procesu przywracania. Więcej informacji o procesach przywracania w chmurze znajdziesz w tym artykule.
  5. Na urządzeniu docelowym użyj aplikacji testowej, aby wywołać interfejs Blockstore API w celu pobrania swoich danych.
  6. Sprawdź, czy pobrane bajty są takie same jak te zapisane na urządzeniu źródłowym.

Wymagania dotyczące urządzenia

Pełne szyfrowanie

  • Pełne szyfrowanie jest obsługiwane na urządzeniach z Androidem 9 (API 29) lub nowszym.
  • Aby można było włączyć pełne szyfrowanie i prawidłowo szyfrować dane użytkownika, urządzenie musi mieć ustawioną blokadę ekranu z kodem PIN, wzorem lub hasłem.

Proces przywracania urządzeń

Przywracanie urządzenia wymaga urządzenia źródłowego i docelowego. To będą 2 urządzenia do przenoszenia danych.

Aby można było tworzyć kopie zapasowe urządzeń źródłowych, musi być zainstalowany Android 6 (API 23) lub nowszy.

Kierowanie na urządzenia z Androidem 9 (API 29) lub nowszym, aby można je było przywrócić.

Więcej informacji na temat procedury przywracania danych z urządzenia znajdziesz tutaj.

Proces tworzenia i przywracania kopii zapasowych w chmurze

Tworzenie i przywracanie kopii zapasowej w chmurze będzie wymagało użycia urządzenia źródłowego i docelowego.

Aby można było tworzyć kopie zapasowe urządzeń źródłowych, musi być zainstalowany Android 6 (API 23) lub nowszy.

Urządzenia docelowe są obsługiwane na podstawie ich dostawców. Urządzenia Pixel mogą używać tej funkcji na urządzeniach z Androidem 9 (API 29), a na wszystkich innych urządzeniach musi być zainstalowany Android 12 (API 31) lub nowszy.