На этой странице описывается, как интерпретировать и работать с возвращаемым вердиктом целостности. Независимо от того, делаете ли вы стандартный или классический запрос 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
не содержит deviceRecognitionVerdict
.
"deviceIntegrity": { // "MEETS_DEVICE_INTEGRITY" is one of several possible values. "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"] }
По умолчанию deviceRecognitionVerdict
может содержать следующее:
-
MEETS_DEVICE_INTEGRITY
- Приложение работает на подлинном и сертифицированном устройстве Android. На устройствах 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! }
Если у вас возникли проблемы с проверкой целостности устройства, убедитесь, что установлена заводская прошивка (например, путём сброса настроек устройства) и загрузчик заблокирован. Вы также можете создать тесты Play Integrity API в Play Console .
Условные метки устройств
Если ваше приложение выпускается в Google Play Games для ПК , deviceRecognitionVerdict
также может содержать следующую метку:
-
MEETS_VIRTUAL_INTEGRITY
- Приложение работает на эмуляторе Android с сервисами Google Play. Эмулятор проходит проверку целостности системы и соответствует основным требованиям совместимости с Android.
Дополнительная информация об устройстве и отзыв устройства
Если вы согласитесь получать дополнительные метки в вердикте о целостности, deviceRecognitionVerdict
может содержать следующие дополнительные метки:
-
MEETS_BASIC_INTEGRITY
- Приложение запущено на устройстве, прошедшем базовые проверки целостности системы. Загрузчик устройства может быть заблокирован или разблокирован, а состояние загрузки может быть верифицированным или неверифицированным. Устройство может быть несертифицированным, в этом случае Google не может предоставить никаких гарантий безопасности, конфиденциальности или совместимости приложения. В Android 13 и более поздних версиях вердикт
MEETS_BASIC_INTEGRITY
требует только, чтобы корень доверия для аттестации был предоставлен Google. -
MEETS_STRONG_INTEGRITY
- Приложение работает на подлинном и сертифицированном устройстве Android с последним обновлением безопасности.
- На устройствах 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 | Недавняя активность устройства не была оценена. Это могло произойти по следующим причинам:
|
Отзыв устройства (бета)
Вы также можете включить функцию отзыва устройств (device recall ), которая позволяет хранить некоторые пользовательские данные для каждого устройства, которые можно будет надежно извлечь при последующей установке приложения на том же устройстве. После запроса токена целостности вы выполняете отдельный вызов между серверами для изменения значений отзыва устройств для конкретного устройства.
Если вы включите 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 приложения для учётной записи пользователя, вошедшего в систему на устройстве. Если у учётной записи пользователя есть лицензия Google 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 Console, ваш ответ 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 Маркет недавно были сброшены.
-
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. Если пользователь не может выполнить эти требования, вы можете заблокировать ему доступ к серверу.