Oceny integralności

Na tej stronie wyjaśniamy, jak interpretować zwrócony werdykt dotyczący integralności i jak z nim pracować. Niezależnie od tego, czy wysyłasz żądanie standardowe, czy klasyczne, ocena integralności jest zwracana w tym samym formacie z podobnymi treściami. Ocena integralności przekazuje informacje o ważności urządzeń, aplikacji i kont. Serwer aplikacji może użyć deszyfrowanego, zweryfikowanego wyniku, aby określić, jak najlepiej wykonać określone działanie lub zrealizować żądanie w aplikacji.

Format zwracanej oceny integralności

Ładunek jest plikiem JSON w czystym tekście i zawiera sygnały integralności oraz informacje od dewelopera.

Ogólna struktura ładunku:

{
  requestDetails: { ... }
  appIntegrity: { ... }
  deviceIntegrity: { ... }
  accountDetails: { ... }
  environmentDetails: { ... }
}

Zanim sprawdzisz każdy werdykt dotyczący integralności, musisz najpierw sprawdzić, czy wartości w polu requestDetails są zgodne z wartościami w pierwotnym żądaniu. W sekcjach poniżej znajdziesz więcej informacji o każdym polu.

Pole Szczegóły żądania

Pole requestDetails zawiera informacje o żądaniu, w tym informacje od dewelopera w polu requestHash w przypadku żądań standardowych i polu nonce w przypadku żądań klasycznych.

W przypadku standardowych żądań do interfejsu API:

requestDetails: {
  // Application package name this attestation was requested for.
  // Note that this field might be spoofed in the middle of the request.
  requestPackageName: "com.package.name"
  // Request hash provided by the developer.
  requestHash: "aGVsbG8gd29scmQgdGhlcmU"
  // The timestamp in milliseconds when the integrity token
  // was requested.
  timestampMillis: "1675655009345"
}

Te wartości powinny być takie same jak w pierwotnym żądaniu. Dlatego sprawdź część requestDetails ładunku JSON, upewniając się, że wartości requestPackageName i requestHash są zgodne z tym, co zostało wysłane w pierwotnym żądaniu, jak pokazano w tym fragmencie kodu:

Kotlin

val requestDetails = JSONObject(payload).getJSONObject("requestDetails")
val requestPackageName = requestDetails.getString("requestPackageName")
val requestHash = requestDetails.getString("requestHash")
val timestampMillis = requestDetails.getLong("timestampMillis")
val currentTimestampMillis = ...

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request
    || !requestHash.equals(expectedRequestHash)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Java

RequestDetails requestDetails =
    decodeIntegrityTokenResponse
    .getTokenPayloadExternal()
    .getRequestDetails();
String requestPackageName = requestDetails.getRequestPackageName();
String requestHash = requestDetails.getRequestHash();
long timestampMillis = requestDetails.getTimestampMillis();
long currentTimestampMillis = ...;

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request.
    || !requestHash.equals(expectedRequestHash)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

W przypadku żądań klasycznego interfejsu API:

requestDetails: {
  // Application package name this attestation was requested for.
  // Note that this field might be spoofed in the middle of the
  // request.
  requestPackageName: "com.package.name"
  // base64-encoded URL-safe no-wrap nonce provided by the developer.
  nonce: "aGVsbG8gd29scmQgdGhlcmU"
  // The timestamp in milliseconds when the request was made
  // (computed on the server).
  timestampMillis: "1617893780"
}

Te wartości powinny być takie same jak w pierwotnym żądaniu. Dlatego sprawdź część requestDetails ładunku JSON, upewniając się, że wartości requestPackageName i nonce są zgodne z tym, co zostało wysłane w pierwotnym żądaniu, jak pokazano w tym fragmencie kodu:

Kotlin

val requestDetails = JSONObject(payload).getJSONObject("requestDetails")
val requestPackageName = requestDetails.getString("requestPackageName")
val nonce = requestDetails.getString("nonce")
val timestampMillis = requestDetails.getLong("timestampMillis")
val currentTimestampMillis = ...

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request. See 'Generate a nonce'
        // section of the doc on how to store/compute the expected nonce.
    || !nonce.equals(expectedNonce)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Java

JSONObject requestDetails =
    new JSONObject(payload).getJSONObject("requestDetails");
String requestPackageName = requestDetails.getString("requestPackageName");
String nonce = requestDetails.getString("nonce");
long timestampMillis = requestDetails.getLong("timestampMillis");
long currentTimestampMillis = ...;

// Ensure the token is from your app.
if (!requestPackageName.equals(expectedPackageName)
        // Ensure the token is for this specific request. See 'Generate a nonce'
        // section of the doc on how to store/compute the expected nonce.
    || !nonce.equals(expectedNonce)
        // Ensure the freshness of the token.
    || currentTimestampMillis - timestampMillis > ALLOWED_WINDOW_MILLIS) {
        // The token is invalid! See below for further checks.
        ...
}

Pole integralności aplikacji

Pole appIntegrity zawiera informacje o pakiecie.

appIntegrity: {
  // PLAY_RECOGNIZED, UNRECOGNIZED_VERSION, or UNEVALUATED.
  appRecognitionVerdict: "PLAY_RECOGNIZED"
  // The package name of the app.
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  packageName: "com.package.name"
  // The sha256 digest of app certificates (base64-encoded URL-safe).
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  certificateSha256Digest: ["6a6a1474b5cbbb2b1aa57e0bc3"]
  // The version of the app.
  // This field is populated iff appRecognitionVerdict != UNEVALUATED.
  versionCode: "42"
}

appRecognitionVerdict może mieć te wartości:

PLAY_RECOGNIZED
Aplikacja i certyfikat odpowiadają wersjom rozpowszechnianym w Google Play.
UNRECOGNIZED_VERSION
Nazwa certyfikatu lub pakietu nie odpowiada rekordom Google Play.
UNEVALUATED
Integralność aplikacji nie została określona. Pominięto niezbędny wymóg, np. urządzenie nie było wystarczająco godne zaufania.

Aby mieć pewność, że token został wygenerowany przez utworzoną przez Ciebie aplikację, sprawdź, czy integralność aplikacji jest zgodna z oczekiwaniami, jak pokazano w tym fragmencie kodu:

Kotlin

val appIntegrity = JSONObject(payload).getJSONObject("appIntegrity")
val appRecognitionVerdict = appIntegrity.getString("appRecognitionVerdict")

if (appRecognitionVerdict == "PLAY_RECOGNIZED") {
    // Looks good!
}

Java

JSONObject appIntegrity =
    new JSONObject(payload).getJSONObject("appIntegrity");
String appRecognitionVerdict =
    appIntegrity.getString("appRecognitionVerdict");

if (appRecognitionVerdict.equals("PLAY_RECOGNIZED")) {
    // Looks good!
}

Możesz też ręcznie sprawdzić nazwę pakietu aplikacji, wersję aplikacji i certyfikaty aplikacji.

Pole integralności urządzenia

Pole deviceIntegrity może zawierać jedną wartość, deviceRecognitionVerdict, która ma co najmniej 1 etykietę wskazującą, jak dobrze urządzenie może egzekwować integralność aplikacji. Jeśli urządzenie nie spełnia kryteriów żadnych etykiet, pole deviceIntegrity jest puste.

deviceIntegrity: {
  // "MEETS_DEVICE_INTEGRITY" is one of several possible values.
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
}

Domyślnie deviceRecognitionVerdict może zawierać:

MEETS_DEVICE_INTEGRITY
Aplikacja działa na urządzeniu z Androidem z Usługami Google Play. Urządzenie przeszło testy integralności systemu i jest zgodne z Androidem.
Pusty (pusta wartość)
Aplikacja działa na urządzeniu, na którym pojawiły się oznaki ataku (np. punkt zaczepienia w interfejsie API) lub naruszenia systemu (np. dostęp do roota), albo aplikacja nie działa na urządzeniu fizycznym (tylko np. na emulatorze, który nie przeszedł testów integralności Google Play).

Aby mieć pewność, że token pochodzi z godnego zaufania urządzenia, sprawdź, czy deviceRecognitionVerdict jest zgodny z oczekiwaniami, jak pokazano w tym fragmencie kodu:

Kotlin

val deviceIntegrity =
    JSONObject(payload).getJSONObject("deviceIntegrity")
val deviceRecognitionVerdict =
    if (deviceIntegrity.has("deviceRecognitionVerdict")) {
        deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString()
    } else {
        ""
    }

if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) {
    // Looks good!
}

Java

JSONObject deviceIntegrity =
    new JSONObject(payload).getJSONObject("deviceIntegrity");
String deviceRecognitionVerdict =
    deviceIntegrity.has("deviceRecognitionVerdict")
    ? deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString()
    : "";

if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) {
    // Looks good!
}

Jeśli masz problemy z sprawdzaniem integralności urządzenia, upewnij się, że zainstalowana jest fabryczna pamięć ROM (np. przez zresetowanie urządzenia) i że bootloader jest zablokowany. Możesz też tworzyć testy Play Integrity API w Konsoli Play.

Etykiety urządzeń warunkowych

Jeśli Twoja aplikacja jest dostępna w Grach Google Play na PC, deviceRecognitionVerdict może też zawierać tę etykietę:

MEETS_VIRTUAL_INTEGRITY
Aplikacja działa w narzędziu Android Emulator z Usługami Google Play. Emulator przeszedł testy integralności systemu i spełnia podstawowe wymagania dotyczące zgodności z Androidem.

Opcjonalne informacje o urządzeniu

Jeśli wyraźisz zgodę na otrzymywanie dodatkowych etykiet w ocenie integralności, deviceRecognitionVerdict może zawierać te dodatkowe etykiety:

MEETS_BASIC_INTEGRITY
Aplikacja działa na urządzeniu, które przeszło podstawowe testy integralności systemu. Urządzenie może być niezgodne z Androidem i mogło nie zostać zatwierdzone do uruchamiania Usług Google Play. Na przykład może korzystać z nierozpoznanej wersji Androida, mieć odblokowany program rozruchowy lub nie mieć certyfikatu producenta.
MEETS_STRONG_INTEGRITY
Aplikacja działa na urządzeniu z Androidem z Usługami Google Play. Gwarancja integralności systemu jest wysoka – np. dzięki sprzętowemu potwierdzeniu integralności rozruchu. Urządzenie przeszło testy integralności systemu i jest zgodne z Androidem.

Jedno urządzenie zwróci wiele etykiet urządzenia w wyroku dotyczącym integralności urządzenia, jeśli zostaną spełnione wszystkie kryteria.

Ostatnia aktywność na urządzeniu

Możesz też włączyć funkcję „Ostatnia aktywność na urządzeniu”, która informuje, ile razy aplikacja zażądała tokena integralności na określonym urządzeniu w ciągu ostatniej godziny. Możesz użyć ostatniej aktywności urządzenia, aby chronić swoją aplikację przed nieoczekiwanymi, nadmiernie aktywnymi urządzeniami, które mogą wskazywać na aktywny atak. Możesz określić, na ile ufasz poszczególnym poziomom ostatniej aktywności na urządzeniu na podstawie tego, ile razy aplikacja zainstalowana na typowym urządzeniu wysyła żądanie tokena integralności w ciągu godziny.

Jeśli zdecydujesz się otrzymywać dane recentDeviceActivity, pole deviceIntegrity będzie zawierać 2 wartości:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  recentDeviceActivity: {
    // "LEVEL_2" is one of several possible values.
    deviceActivityLevel: "LEVEL_2"
  }
}

Definicje deviceActivityLevel różnią się w zależności od trybu i mogą mieć jedną z tych wartości:

Ostatnia aktywność na urządzeniu Żądania tokena integralności standardowego interfejsu API na tym urządzeniu w ciągu ostatniej godziny (na aplikację) Żądania tokena integralności klasycznego interfejsu API na tym urządzeniu w ciągu ostatniej godziny (według aplikacji)
LEVEL_1 (najniższa) 10 lub mniej 5 lub mniej
LEVEL_2 Od 11 do 25 lat Od 6 do 10
LEVEL_3 Od 26 do 50 Od 11 do 15
LEVEL_4 (najwyższa) Ponad 50 Ponad 15
UNEVALUATED Ostatnia aktywność na urządzeniu nie została oceniona. Może się tak zdarzyć, ponieważ:
  • Urządzenie nie jest wystarczająco zaufane.
  • Google Play nie rozpoznaje wersji aplikacji zainstalowanej na urządzeniu.
  • problemy techniczne na urządzeniu.

Atrybuty urządzenia

Możesz też wyrazić zgodę na atrybuty urządzenia, które wskazują wersję pakietu Android SDK systemu Androida działającego na urządzeniu. W przyszłości może zostać rozszerzony o inne atrybuty urządzenia.

Wartość wersji pakietu SDK to numer wersji pakietu Android SDK zdefiniowany w Build.VERSION_CODES. Wersja pakietu SDK nie jest oceniana, jeśli pominięto niezbędny wymóg. W tym przypadku pole sdkVersion nie jest ustawione, więc pole deviceAttributes jest puste. Może się tak zdarzyć, jeśli:

  • Urządzenie nie jest wystarczająco zaufane.
  • Google Play nie rozpoznaje wersji aplikacji zainstalowanej na urządzeniu.
  • Wystąpiły problemy techniczne z urządzeniem.

Jeśli zdecydujesz się otrzymywać deviceAttributes, pole deviceIntegrity będzie zawierać to dodatkowe pole:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  deviceAttributes: {
    // 33 is one possible value, which represents Android 13 (Tiramisu).
    sdkVersion: 33
  }
}

Jeśli wersja pakietu SDK nie zostanie oceniona, pole deviceAttributes zostanie ustawione w ten sposób:

deviceIntegrity: {
  deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"]
  deviceAttributes: {}  // sdkVersion field is not set.
}

Pole Szczegóły konta

Pole accountDetails zawiera jedną wartość, appLicensingVerdict, która reprezentuje stan licencjonowania aplikacji w Google Play dla zalogowanego na urządzeniu konta użytkownika. Jeśli konto użytkownika ma licencję na aplikację z Google Play, oznacza to, że została ona pobrana lub kupiona w Google Play.

accountDetails: {
  // This field can be LICENSED, UNLICENSED, or UNEVALUATED.
  appLicensingVerdict: "LICENSED"
}

appLicensingVerdict może mieć jedną z tych wartości:

LICENSED
Użytkownik ma uprawnienia do korzystania z aplikacji. To znaczy, że zainstalował lub zaktualizował Twoją aplikację z Google Play na swoim urządzeniu.
UNLICENSED
Użytkownik nie ma uprawnień do korzystania z aplikacji. Może się tak zdarzyć, jeśli np. zainstaluje ją z innego urządzenia lub nie pozyska jej z Google Play. Aby to naprawić, możesz wyświetlić użytkownikom okno GET_LICENSED.
UNEVALUATED

Szczegóły dotyczące licencji nie zostały zweryfikowane, ponieważ pominięto niezbędny wymóg.

Może się tak zdarzyć z kilku powodów. Oto niektóre z nich:

  • Urządzenie nie jest wystarczająco zaufane.
  • Google Play nie rozpoznaje wersji aplikacji zainstalowanej na urządzeniu.
  • Użytkownik nie jest zalogowany w Google Play.

Aby sprawdzić, czy użytkownik ma uprawnienia do aplikacji, sprawdź, czy wartość parametru appLicensingVerdict jest prawidłowa, jak pokazano w tym fragmencie kodu:

Kotlin

val accountDetails = JSONObject(payload).getJSONObject("accountDetails")
val appLicensingVerdict = accountDetails.getString("appLicensingVerdict")

if (appLicensingVerdict == "LICENSED") {
    // Looks good!
}

Java

JSONObject accountDetails =
    new JSONObject(payload).getJSONObject("accountDetails");
String appLicensingVerdict = accountDetails.getString("appLicensingVerdict");

if (appLicensingVerdict.equals("LICENSED")) {
    // Looks good!
}

Pole szczegółów środowiska

Możesz też wyrazić zgodę na otrzymywanie dodatkowych sygnałów dotyczących środowiska. Ryzyko związane z dostępem aplikacji informuje aplikację, czy uruchomione są inne aplikacje, które mogą rejestrować to, co widać na ekranie, wyświetlać nakładki lub sterować urządzeniem. Ocena Play Protect informuje, czy usługa Google Play Protect jest włączona na urządzeniu i czy wykryła znane złośliwe oprogramowanie.

Jeśli w Konsoli Google Play włączysz ocenę ryzyka dostępu do aplikacji lub ocenę Play Protect, odpowiedź interfejsu API będzie zawierać pole environmentDetails. Pole environmentDetails może zawierać 2 wartości: appAccessRiskVerdictplayProtectVerdict.

Ocena ryzyka dotyczącego dostępu do aplikacji

Po włączeniu tego pola pole environmentDetails w pliku danych interfejsu Play Integrity API będzie zawierać nową ocenę ryzyka związanego z dostępem do aplikacji.

{
  requestDetails: { ... }
  appIntegrity: { ... }
  deviceIntegrity: { ... }
  accountDetails: { ... }
  environmentDetails: {
      appAccessRiskVerdict: {
          // This field contains one or more responses, for example the following.
          appsDetected: ["KNOWN_INSTALLED", "UNKNOWN_INSTALLED", "UNKNOWN_CAPTURING"]
      }
 }
}

Jeśli ryzyko związane z dostępem aplikacji zostało ocenione, element appAccessRiskVerdict zawiera pole appsDetected z co najmniej 1 odpowiedzią. Te odpowiedzi należą do jednej z tych 2 grup, w zależności od źródła instalacji wykrytych aplikacji:

  • Aplikacje z Google Play lub aplikacje systemowe: aplikacje zainstalowane przez Google Play lub wstępnie załadowane przez producenta urządzenia na partycji systemowej urządzenia (oznaczone jako FLAG_SYSTEM). Odpowiedzi na pytania dotyczące takich aplikacji mają przedrostek KNOWN_.

  • Inne aplikacje: aplikacje, które nie zostały zainstalowane przez Google Play. Nie dotyczy to aplikacji wstępnie załadowanych na partycji systemowej przez producenta urządzenia. Odpowiedzi dla takich aplikacji mają przedrostek UNKNOWN_.

Mogą zostać zwrócone te odpowiedzi:

KNOWN_INSTALLED, UNKNOWN_INSTALLED
Zainstalowane są aplikacje, które pasują do odpowiedniego źródła instalacji.
KNOWN_CAPTURING, UNKNOWN_CAPTURING
Uruchomione są aplikacje z włączonymi uprawnieniami, które mogą służyć do wyświetlania ekranu podczas uruchamiania aplikacji. Wyklucza to wszystkie zweryfikowane usługi ułatwień dostępu znane Google Play na urządzeniu.
KNOWN_CONTROLLING, UNKNOWN_CONTROLLING
Uruchomione są aplikacje z włączonymi uprawnieniami, które mogą służyć do sterowania urządzeniem i bezpośredniego sterowania danymi wejściowymi w aplikacji, a także do rejestrowania danych wejściowych i wyjściowych aplikacji. Nie dotyczy to zweryfikowanych usług ułatwień dostępu znanych Google Play, które są uruchomione na urządzeniu.
KNOWN_OVERLAYS, UNKNOWN_OVERLAYS
Uruchomione są aplikacje z włączonymi uprawnieniami, które mogą wyświetlać nakładki na Twoją aplikację. Nie dotyczy to zweryfikowanych usług ułatwień dostępu znanych Google Play, które są uruchomione na urządzeniu.
Pusty (pusta wartość)

Ryzyko dotyczące dostępu do aplikacji nie jest oceniane, jeśli pominięto niezbędny wymóg. W tym przypadku pole appAccessRiskVerdict jest puste. Może się tak zdarzyć z kilku powodów, m.in.:

  • Urządzenie nie jest wystarczająco zaufane.
  • Urządzenie nie jest telefonem, tabletem ani składanym urządzeniem.
  • Urządzenie nie ma zainstalowanego Androida 6 (poziom interfejsu API 23) lub nowszego.
  • Google Play nie rozpoznaje wersji aplikacji zainstalowanej na urządzeniu.
  • Wersja Sklepu Google Play na urządzeniu jest nieaktualna.
  • Tylko gry: konto użytkownika nie ma licencji na grę w Google Play.
  • Użyto standardowego żądania z parametrem verdictOptOut.
  • Użyto żądania standardowego z wersją biblioteki Play Integrity API, która nie obsługuje jeszcze ryzyka dotyczącego dostępu do aplikacji w przypadku żądań standardowych.

Ryzyko dostępu do aplikacji automatycznie wyklucza zweryfikowane usługi ułatwień dostępu, które zostały sprawdzone pod kątem ułatwień dostępu w Google Play (zainstalowane przez dowolny sklep z aplikacjami na urządzeniu). „Wykluczone” oznacza, że zweryfikowane usługi ułatwień dostępu działające na urządzeniu nie zwracają odpowiedzi dotyczących rejestrowania, kontrolowania ani nakładania się na aplikację w ocenie ryzyka związanego z dostępem aplikacji. Aby poprosić o rozszerzone sprawdzenie aplikacji ułatwiającej dostępność w Google Play, opublikuj ją w Google Play i upewnij się, że w pliku manifestu aplikacji flaga isAccessibilityTool ma wartość true. Możesz też poprosić o sprawdzenie.

W tabeli poniżej znajdziesz przykłady werdyktów i ich znaczenia (tabela nie zawiera wszystkich możliwych wyników):

Przykładowa odpowiedź na ocenę ryzyka dotyczącego dostępu aplikacji Interpretacja
appsDetected:
["KNOWN_INSTALLED"]
Zainstalowane są tylko aplikacje rozpoznawane przez Google Play lub wstępnie załadowane na partycji systemowej przez producenta urządzenia.
Nie ma uruchomionych aplikacji, które mogłyby spowodować wydanie werdyktu dotyczącego przechwytywania, sterowania lub nakładek.
appsDetected:
["KNOWN_INSTALLED",
"UNKNOWN_INSTALLED",
"UNKNOWN_CAPTURING"]
Aplikacje zainstalowane przez Google Play lub wstępnie załadowane na partycji systemowej przez producenta urządzenia.
Inne aplikacje są uruchomione i mają włączone uprawnienia, które mogą służyć do wyświetlania ekranu lub rejestrowania innych danych wejściowych i wyjściowych.
appsDetected:
["KNOWN_INSTALLED",
"KNOWN_CAPTURING",
"UNKNOWN_INSTALLED",
"UNKNOWN_CONTROLLING"]
Uruchomione są aplikacje Google Play lub systemowe, które mają włączone uprawnienia umożliwiające wyświetlanie ekranu lub przechwytywanie innych danych wejściowych i wyjściowych.
Uruchomione są też inne aplikacje z włączonymi uprawnieniami, które mogą służyć do sterowania urządzeniem i bezpośredniego kontrolowania danych wejściowych w aplikacji.
appAccessRiskVerdict: {} Ryzyko związane z dostępem do aplikacji nie zostało ocenione, ponieważ pominięto niezbędny wymóg. Na przykład urządzenie nie było wystarczająco godne zaufania.

W zależności od poziomu ryzyka możesz zdecydować, które kombinacje ocen są akceptowalne, aby kontynuować, i jakie oceny chcesz uwzględnić. Ten fragment kodu pokazuje przykład weryfikacji, czy nie są uruchomione żadne aplikacje, które mogą rejestrować to, co widać na ekranie, lub kontrolować Twoją aplikację:

Kotlin

val environmentDetails =
    JSONObject(payload).getJSONObject("environmentDetails")
val appAccessRiskVerdict =
    environmentDetails.getJSONObject("appAccessRiskVerdict")

if (appAccessRiskVerdict.has("appsDetected")) {
    val appsDetected = appAccessRiskVerdict.getJSONArray("appsDetected").toString()
    if (!appsDetected.contains("CAPTURING") && !appsDetected.contains("CONTROLLING")) {
        // Looks good!
    }
}

Java

JSONObject environmentDetails =
    new JSONObject(payload).getJSONObject("environmentDetails");
JSONObject appAccessRiskVerdict =
    environmentDetails.getJSONObject("appAccessRiskVerdict");

if (appAccessRiskVerdict.has("appsDetected")) {
    String appsDetected = appAccessRiskVerdict.getJSONArray("appsDetected").toString()
    if (!appsDetected.contains("CAPTURING") && !appsDetected.contains("CONTROLLING")) {
        // Looks good!
    }
}
Naprawianie ocen ryzyka dotyczącego dostępu do aplikacji

W zależności od poziomu ryzyka możesz określić, w przypadku których ocen ryzyka dotyczącego dostępu do aplikacji chcesz podjąć działanie, zanim użytkownik wykona żądanie lub działanie. Po sprawdzeniu wyniku oceny ryzyka dotyczącego dostępu do aplikacji możesz wyświetlić użytkownikowi opcjonalne komunikaty Google Play. Możesz wyświetlić CLOSE_UNKNOWN_ACCESS_RISK, aby poprosić użytkownika o zamknięcie nieznanych aplikacji, które spowodowały wynik ryzyka dotyczącego dostępu do aplikacji, lub CLOSE_ALL_ACCESS_RISK, aby poprosić użytkownika o zamknięcie wszystkich aplikacji (znanych i nieznanych), które spowodowały wynik ryzyka dotyczącego dostępu do aplikacji.

Werdykt Play Protect

Po włączeniu interfejsu Play Integrity API pole environmentDetailsdanych payloadu będzie zawierać ocenę Play Protect:

environmentDetails: {
  playProtectVerdict: "NO_ISSUES"
}

playProtectVerdict może mieć jedną z tych wartości:

NO_ISSUES
Usługa Play Protect jest włączona i nie wykryła żadnych problemów z aplikacją na urządzeniu.
NO_DATA
Ochrona Play Protect jest włączona, ale skanowanie nie zostało jeszcze wykonane. Urządzenie lub aplikacja Sklep Play mogły zostać niedawno zresetowane.
POSSIBLE_RISK
Usługa Play Protect jest wyłączona.
MEDIUM_RISK
Usługa Play Protect jest włączona i wykryła zainstalowane na urządzeniu potencjalnie szkodliwe aplikacje.
HIGH_RISK
Usługa Play Protect jest włączona i wykryła zainstalowane na urządzeniu niebezpieczne aplikacje.
UNEVALUATED

Wynik Play Protect nie został oceniony.

Może się tak zdarzyć z kilku powodów. Oto niektóre z nich:

  • Urządzenie nie jest wystarczająco zaufane.
  • Tylko gry: konto użytkownika nie ma licencji na grę w Google Play.

Wskazówki dotyczące korzystania z wyroku Play Protect

Na podstawie dokonanej oceny serwer backendu aplikacji może podjąć odpowiednie działania, które mają na celu ograniczenie ataków, nadużyć i nieautoryzowanego dostępu. Oto kilka sugestii i potencjalnych działań użytkownika:

NO_ISSUES
Usługa Play Protect jest włączona i nie wykryła żadnych problemów, więc użytkownik nie musi nic robić.
POSSIBLE_RISKNO_DATA
Gdy otrzymasz te oceny, poproś użytkownika, aby sprawdził, czy funkcja Play Protect jest włączona i czy przeprowadzono skanowanie. NO_DATA powinien pojawiać się tylko w niektórych przypadkach.
MEDIUM_RISKHIGH_RISK
W zależności od tolerancji na ryzyko możesz poprosić użytkownika o uruchomienie Play Protect i podjęcie działań w reakcji na ostrzeżenia Play Protect. Jeśli użytkownik nie spełnia tych wymagań, możesz zablokować mu dostęp do działania serwera.