На этой странице описывается, как интерпретировать и работать с возвращаемым вердиктом целостности. Независимо от того, делаете ли вы стандартный или классический запрос API, вердикт целостности возвращается в том же формате с похожим содержимым. Вердикт целостности передает информацию о действительности устройств, приложений и учетных записей. Сервер вашего приложения может использовать полученную полезную нагрузку в расшифрованном, проверенном вердикте, чтобы определить, как лучше всего продолжить определенное действие или запрос в вашем приложении.
Формат вердикта о возвращенной целостности
Полезная нагрузка представляет собой простой текст JSON и содержит сигналы целостности, а также информацию, предоставленную разработчиком.
Общая структура полезной нагрузки выглядит следующим образом:
{ requestDetails: { ... } appIntegrity: { ... } deviceIntegrity: { ... } accountDetails: { ... } environmentDetails: { ... } }
Сначала необходимо проверить, что значения в поле requestDetails
соответствуют значениям исходного запроса, прежде чем проверять каждый вердикт о целостности. В следующих разделах каждое поле описывается более подробно.
Запросить поле деталей
Поле requestDetails
содержит информацию о запросе, включая предоставленную разработчиком информацию в requestHash
для стандартных запросов и nonce
для классических запросов.
Для стандартных запросов 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" }
Эти значения должны соответствовать значениям исходного запроса. Поэтому проверьте часть requestDetails
полезной нагрузки JSON, убедившись, что requestPackageName
и requestHash
соответствуют значениям, отправленным в исходном запросе, как показано в следующем фрагменте кода:
Котлин
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. ... }
Ява
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. ... }
Для классических 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" }
Эти значения должны соответствовать значениям исходного запроса. Поэтому проверьте часть requestDetails
полезной нагрузки JSON, убедившись, что requestPackageName
и nonce
соответствуют значениям, отправленным в исходном запросе, как показано в следующем фрагменте кода:
Котлин
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. ... }
Ява
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. ... }
Поле целостности приложения
Поле appIntegrity
содержит информацию, связанную с пакетом.
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
может иметь следующие значения:
-
PLAY_RECOGNIZED
- Приложение и сертификат соответствуют версиям, распространяемым Google Play.
-
UNRECOGNIZED_VERSION
- Имя сертификата или пакета не соответствует записям Google Play.
-
UNEVALUATED
- Целостность приложения не была оценена. Необходимое требование было пропущено, например, устройство не было достаточно надежным.
Чтобы убедиться, что токен был сгенерирован приложением, созданным вами, проверьте, что целостность приложения соответствует ожидаемой, как показано в следующем фрагменте кода:
Котлин
val appIntegrity = JSONObject(payload).getJSONObject("appIntegrity") val appRecognitionVerdict = appIntegrity.getString("appRecognitionVerdict") if (appRecognitionVerdict == "PLAY_RECOGNIZED") { // Looks good! }
Ява
JSONObject appIntegrity = new JSONObject(payload).getJSONObject("appIntegrity"); String appRecognitionVerdict = appIntegrity.getString("appRecognitionVerdict"); if (appRecognitionVerdict.equals("PLAY_RECOGNIZED")) { // Looks good! }
Вы также можете вручную проверить имя пакета приложения, версию приложения и сертификаты приложения.
Поле целостности устройства
Поле deviceIntegrity
может содержать одно значение, deviceRecognitionVerdict
, которое имеет одну или несколько меток, представляющих, насколько хорошо устройство может обеспечивать целостность приложения. Если устройство не соответствует критериям ни одной метки, поле deviceIntegrity
пусто.
deviceIntegrity: { // "MEETS_DEVICE_INTEGRITY" is one of several possible values. deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"] }
По умолчанию deviceRecognitionVerdict
может содержать следующее:
-
MEETS_DEVICE_INTEGRITY
- Приложение работает на подлинном устройстве Android, сертифицированном Play Protect. На Android 13 и выше есть аппаратное подтверждение того, что загрузчик устройства заблокирован, а загруженная ОС Android является сертифицированным образом производителя устройства.
- Пусто (пустое значение)
- Приложение запущено на устройстве, имеющем признаки атаки (например, перехват API) или взлома системы (например, наличие прав root), или приложение запущено не на физическом устройстве (например, эмулятор, не прошедший проверку целостности Google Play).
Чтобы убедиться, что токен поступил от надежного устройства, проверьте, что deviceRecognitionVerdict
соответствует ожидаемому значению, как показано в следующем фрагменте кода:
Котлин
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! }
Ява
JSONObject deviceIntegrity = new JSONObject(payload).getJSONObject("deviceIntegrity"); String deviceRecognitionVerdict = deviceIntegrity.has("deviceRecognitionVerdict") ? deviceIntegrity.getJSONArray("deviceRecognitionVerdict").toString() : ""; if (deviceRecognitionVerdict.contains("MEETS_DEVICE_INTEGRITY")) { // Looks good! }
Если у вас возникли проблемы с целостностью вашего тестового устройства, убедитесь, что установлена заводская прошивка (например, путем сброса устройства) и что загрузчик заблокирован. Вы также можете создать тесты API целостности Play в Play Console .
Условные метки устройств
Если ваше приложение публикуется в Google Play Games для ПК , deviceRecognitionVerdict
также может содержать следующую метку:
-
MEETS_VIRTUAL_INTEGRITY
- Приложение работает на эмуляторе Android с сервисами Google Play. Эмулятор проходит проверку целостности системы и соответствует основным требованиям совместимости Android.
Дополнительная информация об устройстве и отзыв устройства
Если вы согласитесь получать дополнительные метки в вердикте о целостности, deviceRecognitionVerdict
может содержать следующие дополнительные метки:
-
MEETS_BASIC_INTEGRITY
- Приложение запущено на устройстве, которое прошло базовые проверки целостности системы. Загрузчик устройства может быть заблокирован или разблокирован, а состояние загрузки может быть проверено или не проверено. Устройство может не иметь сертификата Play Protect, в этом случае Google не может предоставить никаких гарантий безопасности, конфиденциальности или совместимости приложений. На Android 13 и выше вердикт
MEETS_BASIC_INTEGRITY
требует только, чтобы корень доверия подтверждения был предоставлен Google. -
MEETS_STRONG_INTEGRITY
- Приложение работает на настоящем устройстве Android, сертифицированном Play Protect, с последним обновлением безопасности.
- На Android 13 и выше вердикт
MEETS_STRONG_INTEGRITY
требуетMEETS_DEVICE_INTEGRITY
и обновлений безопасности за последний год для всех разделов устройства, включая исправление раздела ОС Android и исправление раздела поставщика. - На Android 12 и ниже вердикт
MEETS_STRONG_INTEGRITY
требует только аппаратного подтверждения целостности загрузки и не требует, чтобы устройство имело последнее обновление безопасности. Поэтому при использованииMEETS_STRONG_INTEGRITY
рекомендуется также учитывать версию Android SDK в полеdeviceAttributes
.
- На Android 13 и выше вердикт
Одно устройство вернет несколько меток в вердикте о целостности устройства, если выполняется каждый из критериев метки.
Атрибуты устройства
Вы также можете выбрать атрибуты устройства, которые сообщают версию Android SDK ОС Android, работающей на устройстве. В будущем это может быть расширено другими атрибутами устройства.
Значение версии SDK — это номер версии Android SDK, определенный в Build.VERSION_CODES
. Версия SDK не оценивается, если необходимое требование было пропущено. В этом случае поле sdkVersion
не установлено; таким образом, поле deviceAttributes
пусто. Это могло произойти по следующим причинам:
- Устройство недостаточно надежно.
- На устройстве возникли технические неполадки.
Если вы согласитесь получать deviceAttributes
, поле deviceIntegrity
будет иметь следующее дополнительное поле:
deviceIntegrity: { deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"] deviceAttributes: { // 33 is one possible value, which represents Android 13 (Tiramisu). sdkVersion: 33 } }
Если версия SDK не оценена, поле deviceAttributes
будет установлено следующим образом:
deviceIntegrity: { deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"] deviceAttributes: {} // sdkVersion field is not set. }
Недавняя активность устройства
Вы также можете выбрать недавнюю активность устройства, которая сообщает вам, сколько раз ваше приложение запрашивало токен целостности на определенном устройстве за последний час. Вы можете использовать недавнюю активность устройства, чтобы защитить свое приложение от неожиданных, гиперактивных устройств, которые могут быть признаком активной атаки. Вы можете решить, насколько доверять каждому уровню недавней активности устройства, основываясь на том, сколько раз, как вы ожидаете, ваше приложение, установленное на типичном устройстве, будет запрашивать токен целостности в течение каждого часа.
Если вы согласитесь получать recentDeviceActivity
, поле deviceIntegrity
будет иметь два значения:
deviceIntegrity: { deviceRecognitionVerdict: ["MEETS_DEVICE_INTEGRITY"] recentDeviceActivity: { // "LEVEL_2" is one of several possible values. deviceActivityLevel: "LEVEL_2" } }
Определения deviceActivityLevel
различаются в зависимости от режима и могут иметь одно из следующих значений:
Уровень активности последнего устройства | Стандартные запросы на маркер целостности API на этом устройстве за последний час для каждого приложения | Запросы токена целостности классического API на этом устройстве за последний час для каждого приложения |
---|---|---|
LEVEL_1 (самый низкий) | 10 или меньше | 5 или меньше |
LEVEL_2 | Между 11 и 25 | Между 6 и 10 |
LEVEL_3 | От 26 до 50 | Между 11 и 15 |
LEVEL_4 (высший) | Более 50 | Более 15 |
UNEVALUATED | Недавняя активность устройства не была оценена. Это могло произойти по следующим причинам:
|
Отзыв устройства (бета)
Вы также можете выбрать отзыв устройства , который позволяет вам хранить некоторые пользовательские данные для каждого устройства с определенными устройствами, которые вы можете надежно извлечь, когда ваше приложение будет установлено снова на том же устройстве. После запроса токена целостности вы делаете отдельный вызов сервер-сервер, чтобы изменить значения отзыва устройства для определенного устройства.
Если вы включили deviceRecall
, поле deviceIntegrity
будет содержать информацию об отзыве устройства, которую вы установили для конкретного устройства:
"deviceIntegrity": {
"deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"],
"deviceRecall": {
"values": {
"bitFirst": true,
"bitSecond": false,
"bitThird": true
},
"writeDates": {
// Write time in YYYYMM format in UTC.
"yyyymmFirst": 202401,
// Note that yyyymmSecond is not set because bitSecond is false.
"yyyymmThird": 202310
}
}
}
deviceRecall
разделен на два поля:
-
values
: вызов значений битов, которые вы ранее установили для этого устройства. -
writeDates
: Вызов дат записи бита в формате UTC с точностью до года и месяца. Дата записи бита отзыва будет обновляться каждый раз, когда бит устанавливается вtrue
и будет удалена, когда бит устанавливается вfalse
.
В случае, если информация об отзыве устройства недоступна, значение отзыва устройства будет пустым:
"deviceIntegrity": {
"deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"],
"deviceRecall": {
"values": {},
"writeDates": {}
}
}
Поле реквизитов счета
Поле accountDetails
содержит единственное значение, appLicensingVerdict
, которое представляет статус лицензирования приложения Google Play для учетной записи пользователя, вошедшей в систему на устройстве. Если учетная запись пользователя имеет лицензию Play для приложения, это означает, что он загрузил его или купил в Google Play.
accountDetails: { // This field can be LICENSED, UNLICENSED, or UNEVALUATED. appLicensingVerdict: "LICENSED" }
appLicensingVerdict
может иметь одно из следующих значений:
-
LICENSED
- У пользователя есть право на приложение. Другими словами, пользователь установил или обновил ваше приложение из Google Play на своем устройстве.
-
UNLICENSED
- У пользователя нет права на приложение. Это происходит, например, когда пользователь загружает ваше приложение извне или не приобретает его из Google Play. Вы можете показать пользователям диалоговое окно GET_LICENSED , чтобы исправить это.
-
UNEVALUATED
Детали лицензирования не были оценены, поскольку было пропущено необходимое требование.
Это может произойти по нескольким причинам, включая следующие:
- Устройство недостаточно надежно.
- Версия вашего приложения, установленного на устройстве, неизвестна Google Play.
- Пользователь не авторизован в Google Play.
Чтобы проверить, есть ли у пользователя права на ваше приложение, проверьте, что appLicensingVerdict
соответствует ожидаемому значению, как показано в следующем фрагменте кода:
Котлин
val accountDetails = JSONObject(payload).getJSONObject("accountDetails") val appLicensingVerdict = accountDetails.getString("appLicensingVerdict") if (appLicensingVerdict == "LICENSED") { // Looks good! }
Ява
JSONObject accountDetails = new JSONObject(payload).getJSONObject("accountDetails"); String appLicensingVerdict = accountDetails.getString("appLicensingVerdict"); if (appLicensingVerdict.equals("LICENSED")) { // Looks good! }
Поле сведений об окружающей среде
Вы также можете выбрать дополнительные сигналы об окружающей среде. Риск доступа к приложению сообщает вашему приложению, запущены ли другие приложения, которые могут использоваться для захвата экрана, отображения наложений или управления устройством. Вердикт Play Protect сообщает вам, включена ли на устройстве защита Google Play и обнаружено ли известное вредоносное ПО.
Если вы выбрали вердикт App Access Risk или вердикт Play Protect в своей консоли Google Play, то ваш ответ API будет включать поле environmentDetails
. Поле environmentDetails
может содержать два значения: appAccessRiskVerdict
и playProtectVerdict
.
Вердикт о риске доступа к приложению
После включения поле environmentDetails
в полезной нагрузке API Play Integrity будет содержать новый вердикт о риске доступа к приложению.
{
requestDetails: { ... }
appIntegrity: { ... }
deviceIntegrity: { ... }
accountDetails: { ... }
environmentDetails: {
appAccessRiskVerdict: {
// This field contains one or more responses, for example the following.
appsDetected: ["KNOWN_INSTALLED", "UNKNOWN_INSTALLED", "UNKNOWN_CAPTURING"]
}
}
}
Если риск доступа к приложению был оценен, appAccessRiskVerdict
содержит поле appsDetected
с одним или несколькими ответами. Эти ответы попадают в одну из следующих двух групп в зависимости от источника установки обнаруженных приложений:
Play или системные приложения : приложения, которые устанавливаются Google Play или предварительно загружаются производителем устройства в системный раздел устройства (идентифицируется с помощью
FLAG_SYSTEM
). Ответы для таких приложений имеют префиксKNOWN_
.Другие приложения : приложения, которые не установлены Google Play. Это исключает приложения, предварительно загруженные в системный раздел производителем устройства. Ответы для таких приложений имеют префикс
UNKNOWN_
.
Могут быть возвращены следующие ответы:
-
KNOWN_INSTALLED
,UNKNOWN_INSTALLED
- Установлены приложения, соответствующие источнику установки.
-
KNOWN_CAPTURING
,UNKNOWN_CAPTURING
- Есть запущенные приложения, у которых включены разрешения, которые могут использоваться для просмотра экрана во время работы вашего приложения. Это исключает любые проверенные службы доступности, известные Google Play, запущенные на устройстве.
-
KNOWN_CONTROLLING
,UNKNOWN_CONTROLLING
- Существуют запущенные приложения, у которых включены разрешения, которые могут использоваться для управления устройством и прямого управления вводом в ваше приложение, а также для захвата вводов и выводов вашего приложения. Это исключает любые проверенные службы доступности, известные Google Play, работающие на устройстве.
-
KNOWN_OVERLAYS
,UNKNOWN_OVERLAYS
- Есть запущенные приложения, у которых включены разрешения, которые могут использоваться для отображения наложений в вашем приложении. Это исключает любые проверенные службы доступности, известные Google Play, запущенные на устройстве.
- Пусто (пустое значение)
Риск доступа к приложению не оценивается, если необходимое требование было пропущено. В этом случае поле
appAccessRiskVerdict
пустое. Это может произойти по нескольким причинам, включая следующие:- Устройство недостаточно надежно.
- Форм-фактор устройства не соответствует типу телефона, планшета или складного устройства.
- Устройство не работает под управлением Android 6 (уровень API 23) или выше.
- Версия вашего приложения, установленного на устройстве, неизвестна Google Play.
- Версия Google Play Store на устройстве устарела.
- Только игры : у учетной записи пользователя нет лицензии Play для игры.
- Использован стандартный запрос с параметром
verdictOptOut
. - Стандартный запрос использовался с версией библиотеки Play Integrity API, которая пока не поддерживает риск доступа к приложению для стандартных запросов.
Риск доступа к приложению автоматически исключает проверенные службы доступности, которые прошли расширенную проверку доступности Google Play (установленную любым магазином приложений на устройстве). «Исключено» означает, что проверенные службы доступности, работающие на устройстве, не будут возвращать ответ захвата, управления или наложения в вердикте риска доступа к приложению. Чтобы запросить расширенную проверку доступности Google Play для вашего приложения доступности, опубликуйте его в Google Play, убедившись, что в манифесте вашего приложения флаг isAccessibilityTool
установлен на значение true, или запросите проверку .
Примеры вердиктов о риске доступа к приложению
В следующей таблице приведены некоторые примеры вердиктов о риске доступа к приложениям и их значение (в этой таблице не перечислены все возможные результаты):
Пример ответа на вердикт о риске доступа к приложению | Интерпретация |
---|---|
appsDetected: ["KNOWN_INSTALLED"] | Устанавливаются только те приложения, которые распознаются Google Play или предварительно загружены в системный раздел производителем устройства. Не запущено ни одного приложения, которое могло бы привести к вердиктам о захвате, управлении или наложении. |
appsDetected: ["KNOWN_INSTALLED", "UNKNOWN_INSTALLED", "UNKNOWN_CAPTURING"] | Существуют приложения, установленные через Google Play или предустановленные в системном разделе производителем устройства. Запущены и другие приложения, которым предоставлены разрешения, позволяющие просматривать экран или захватывать другие входные и выходные данные. |
appsDetected: ["KNOWN_INSTALLED", "KNOWN_CAPTURING", "UNKNOWN_INSTALLED", "UNKNOWN_CONTROLLING"] | Существуют запущенные Play или система с включенными разрешениями, которые можно использовать для просмотра экрана или захвата других входов и выходов. Также запущены другие приложения, имеющие включенные разрешения, которые можно использовать для управления устройством и непосредственного управления вводом данных в ваше приложение. |
appAccessRiskVerdict: {} | Риск доступа к приложению не оценивается, поскольку необходимое требование было пропущено. Например, устройство не было достаточно надежным. |
В зависимости от вашего уровня риска вы можете решить, какая комбинация вердиктов приемлема для продолжения и какие вердикты вы хотите принять меры. Следующий фрагмент кода иллюстрирует пример проверки отсутствия запущенных приложений, которые могли бы захватывать экран или управлять вашим приложением:
Котлин
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! } }
Ява
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! } }
Устранение вердиктов о рисках доступа к приложениям
В зависимости от уровня риска вы можете решить, какие вердикты о риске доступа к приложению вы хотите предпринять, прежде чем позволить пользователю выполнить запрос или действие. Существуют необязательные подсказки Google Play, которые вы можете показать пользователю после проверки вердикта о риске доступа к приложению. Вы можете показать CLOSE_UNKNOWN_ACCESS_RISK , чтобы попросить пользователя закрыть неизвестные приложения, вызывающие вердикт о риске доступа к приложению, или вы можете показать CLOSE_ALL_ACCESS_RISK, чтобы попросить пользователя закрыть все приложения (известные и неизвестные), вызывающие вердикт о риске доступа к приложению.
Вердикт Play Protect
После включения поле environmentDetails
в полезной нагрузке Play Integrity API будет содержать вердикт Play Protect:
environmentDetails: {
playProtectVerdict: "NO_ISSUES"
}
playProtectVerdict
может иметь одно из следующих значений:
-
NO_ISSUES
- Play Protect включен и не обнаружил никаких проблем с приложением на устройстве.
-
NO_DATA
- Play Protect включен, но сканирование еще не проводилось. Возможно, устройство или приложение Play Store недавно были сброшены.
-
POSSIBLE_RISK
- Функция Play Protect отключена.
-
MEDIUM_RISK
- Функция Play Protect включена и обнаружила на устройстве потенциально опасные приложения.
-
HIGH_RISK
- Функция Play Protect включена и обнаружила на устройстве опасные приложения.
-
UNEVALUATED
Вердикт Play Protect не был рассмотрен.
Это может произойти по нескольким причинам, включая следующие:
- Устройство недостаточно надежно.
- Только игры : у учетной записи пользователя нет лицензии Play для игры.
Руководство по использованию вердикта Play Protect
Бэкэнд-сервер вашего приложения может решить, как действовать, основываясь на вердикте, основанном на вашей толерантности к риску. Вот несколько предложений и потенциальных действий пользователя:
-
NO_ISSUES
- Play Protect включен и не обнаружил никаких проблем, поэтому никаких действий со стороны пользователя не требуется.
-
POSSIBLE_RISK
иNO_DATA
- При получении этих вердиктов попросите пользователя проверить, включена ли функция Play Protect и выполнено ли сканирование.
NO_DATA
должен появляться только в редких случаях. -
MEDIUM_RISK
иHIGH_RISK
- В зависимости от вашей толерантности к риску вы можете попросить пользователя запустить Play Protect и принять меры по предупреждениям Play Protect. Если пользователь не может выполнить эти требования, вы можете заблокировать его от действий сервера.