Bütünlük kararları

Bu sayfada, döndürülen bütünlük kararının nasıl yorumlanacağı ve bu kararla nasıl çalışılacağı açıklanmaktadır. Standart veya klasik API isteği göndermiş olmanıza bakılmaksızın bütünlük değerlendirmesi benzer içerikle aynı biçimde döndürülür. Bütünlük değerlendirmesi; cihazların, uygulamaların ve hesapların geçerliliği hakkında bilgi sunar. Uygulamanızın sunucusu, şifresi çözülmüş ve doğrulanmış bir karardaki yükü kullanarak uygulamanızda belirli bir işlem veya istekle ilgili izlenecek en iyi yolu belirleyebilir.

Döndürülen bütünlük değerlendirmesi biçimi

Yük, düz metin JSON'dur ve geliştirici tarafından sağlanan bilgilerin yanı sıra bütünlük sinyallerini içerir.

Genel yük yapısı aşağıdaki gibidir:

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

Her bütünlük değerlendirmesini kontrol etmeden önce requestDetails alanındaki değerlerin orijinal istekteki değerlerle eşleştiğinden emin olmanız gerekir. Aşağıdaki bölümlerde her alan daha ayrıntılı olarak açıklanmıştır.

İstek ayrıntıları alanı

requestDetails alanında istekle ilgili bilgiler yer alır. Standart istekler için requestHash alanında, klasik istekler için de nonce alanında geliştirici tarafından sağlanan bilgiler buna dahildir.

Standart API istekleri için:

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

Bu değerler, orijinal isteğin değerleriyle eşleşmelidir. Bu nedenle, aşağıdaki kod snippet'inde gösterildiği gibi, orijinal istekte gönderilenlerle eşleştiğinden emin olarak JSON yükünün requestDetails bölümünü doğrulayın:requestPackageNamerequestHash

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

Klasik API istekleri için:

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

Bu değerler, orijinal isteğin değerleriyle eşleşmelidir. Bu nedenle, aşağıdaki kod snippet'inde gösterildiği gibi, orijinal istekte gönderilenlerle requestPackageName ve nonce değerlerinin eşleştiğinden emin olarak JSON yükünün requestDetails bölümünü doğrulayın:

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

Uygulama bütünlüğü alanı

appIntegrity alanında paketle ilgili bilgiler yer alır.

"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 aşağıdaki değerleri alabilir:

PLAY_RECOGNIZED
Uygulama ve sertifika, Google Play tarafından dağıtılan sürümlerle eşleşiyor.
UNRECOGNIZED_VERSION
Sertifika veya paket adı, Google Play kayıtlarıyla eşleşmiyor.
UNEVALUATED
Uygulama bütünlüğü değerlendirilmemiştir. Koşullardan biri karşılanmamıştır (örneğin, cihaz yeterince güvenilir olmayabilir).

Jetonun sizin tarafınızdan oluşturulan bir uygulama tarafından oluşturulduğundan emin olmak için aşağıdaki kod snippet'inde gösterildiği gibi uygulama bütünlüğünün beklendiği gibi olduğunu doğrulayın:

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

Uygulama paket adını, uygulama sürümünü ve uygulama sertifikalarını manuel olarak da kontrol edebilirsiniz.

Cihaz bütünlüğü alanı

deviceIntegrity alanında, bir cihazın uygulama bütünlüğünü ne kadar iyi uygulayabildiğini gösteren bir veya daha fazla etiket içeren tek bir değer ( deviceRecognitionVerdict) bulunabilir. Cihaz hiçbir etiketin ölçütlerini karşılamıyorsa deviceIntegrity alanı deviceRecognitionVerdict değerini içermez.

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

Varsayılan olarak deviceRecognitionVerdict aşağıdakileri içerebilir:

MEETS_DEVICE_INTEGRITY
Uygulama, orijinal ve sertifikalı bir Android cihazda çalışıyor. Android 13 ve sonraki sürümlerde, cihaz bootloader'ının kilitli olduğuna ve yüklenen Android işletim sisteminin sertifikalı bir cihaz üreticisi görüntüsü olduğuna dair donanım destekli kanıt bulunur.
Boş (boş değer)
Uygulamanın çalıştığı cihazda saldırı (API kancalama gibi) veya sistem bozulması (rootlanma gibi) belirtileri var ya da uygulama fiziksel bir cihazda çalışmıyor (örneğin, Google Play bütünlük kontrollerini geçmeyen bir emülatörde çalışıyor).

Jetonun güvenilir bir cihazdan geldiğinden emin olmak için aşağıdaki kod snippet'inde gösterildiği gibi deviceRecognitionVerdict değerinin beklendiği gibi olduğunu doğrulayın:

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

Test cihazınızın cihaz bütünlüğüyle ilgili sorun yaşıyorsanız fabrika ROM'unun yüklendiğinden (ör. cihazı sıfırlayarak) ve bootloader'ın kilitlendiğinden emin olun. Ayrıca Play Console'da Play Integrity API testleri oluşturabilirsiniz.

Koşullu cihaz etiketleri

Uygulamanız PC Üzerinde Google Play Games'de yayınlanıyorsa deviceRecognitionVerdict aşağıdaki etiketi de içerebilir:

MEETS_VIRTUAL_INTEGRITY
Uygulama, Google Play Hizmetleri'nin kullanıldığı Android destekli bir emülatörde çalışmaktadır. Emülatör, sistem bütünlüğü kontrollerini geçer ve temel Android uyumluluk şartlarını karşılar.

İsteğe bağlı cihaz bilgileri ve cihaz geri çağırma

Bütünlük değerlendirmesinde ek etiketler almayı etkinleştirirseniz, deviceRecognitionVerdict aşağıdaki ek etiketleri içerebilir:

MEETS_BASIC_INTEGRITY
Uygulama, temel sistem bütünlüğü kontrollerini geçen bir cihazda çalışıyor. Cihaz bootloader'ı kilitli veya kilidi açık olabilir ve başlatma durumu doğrulanmış veya doğrulanmamış olabilir. Cihaz sertifikalı olmayabilir. Bu durumda Google, güvenlik, gizlilik veya uygulama uyumluluğu konusunda herhangi bir garanti veremez. Android 13 ve sonraki sürümlerde, MEETS_BASIC_INTEGRITY değerlendirmesi için yalnızca güven kökünün Google tarafından sağlanması gerekir.
MEETS_STRONG_INTEGRITY
Uygulama, yakın zamanda güvenlik güncellemesi almış, orijinal ve sertifikalı bir Android cihazda çalışıyor.
  • Android 13 ve sonraki sürümlerde MEETS_STRONG_INTEGRITY kararı için cihazın tüm bölümleri (Android işletim sistemi bölümü yaması ve satıcı bölümü yaması dahil) için son bir yılda MEETS_DEVICE_INTEGRITY ve güvenlik güncellemeleri yapılması gerekir.
  • Android 12 ve önceki sürümlerde MEETS_STRONG_INTEGRITY kararı yalnızca donanım destekli başlatma bütünlüğü kanıtı gerektirir ve cihazın yakın zamanda güvenlik güncellemesi almasını gerekmez. Bu nedenle, MEETS_STRONG_INTEGRITY kullanılırken deviceAttributes alanındaki Android SDK sürümünün de dikkate alınması önerilir.

Etiketlerin her birinin ölçütleri karşılandığı takdirde tek bir cihaz, cihaz bütünlüğü kararında birden fazla cihaz etiketi döndürür.

Cihaz özellikleri

Cihazda çalışan Android OS'nin Android SDK sürümünü belirten cihaz özelliklerini de etkinleştirebilirsiniz. Gelecekte diğer cihaz özellikleriyle genişletilebilir.

SDK sürümü değeri, Build.VERSION_CODES içinde tanımlanan Android SDK sürüm numarasıdır. Gerekli bir koşul karşılanmadığında SDK sürümü değerlendirilmez. Bu durumda, sdkVersion alanı ayarlanmamıştır. Bu nedenle, deviceAttributes alanı boştur. Bunun nedeni aşağıdakilerden biri olabilir:

  • Cihaz yeterince güvenilir değildir.
  • Cihazda teknik sorunlar vardı.

deviceAttributes almayı etkinleştirirseniz deviceIntegrity alanında şu ek alan bulunur:

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

SDK sürümü değerlendirilmezse deviceAttributes alanı şu şekilde ayarlanır:

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

Son cihaz etkinliği

Ayrıca, son cihaz etkinliğini de etkinleştirebilirsiniz. Bu özellik, uygulamanızın son bir saat içinde belirli bir cihazda kaç kez bütünlük jetonu istediğini belirtir. Uygulamanızı etkin bir saldırının göstergesi olabilecek beklenmedik hiperaktif cihazlara karşı korumak için son cihaz etkinliğini kullanabilirsiniz. Uygulamanızın, tipik bir cihaza yüklendiğinde her saat kaç kez bütünlük jetonu isteyeceğini tahmin ettiğinize bağlı olarak her bir son cihaz etkinliği düzeyine ne kadar güveneceğinize karar verebilirsiniz.

recentDeviceActivity alanını almayı etkinleştirirseniz deviceIntegrity alanında iki değer bulunur:

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

deviceActivityLevel tanımları modlar arasında farklılık gösterir ve aşağıdaki değerlerden birini alabilir:

Son cihaz etkinliği düzeyi Bu cihazda son bir saat içinde uygulama başına yapılan standart API bütünlük jetonu istekleri Bu cihazda son bir saat içinde uygulama başına yapılan klasik API bütünlük jetonu istekleri
LEVEL_1 (en düşük) 10 veya daha az 5 veya daha az
LEVEL_2 11 ile 25 arasında 6 ile 10 arasında
LEVEL_3 26 ile 50 arasında 11 ile 15 arasında
LEVEL_4 (en yüksek) 50'den fazla 15'ten fazla
UNEVALUATED Son cihaz etkinliği değerlendirilmedi. Bu durumun nedeni şunlar olabilir:
  • Cihaz yeterince güvenilir değildir.
  • Cihazda uygulamanızın Google Play tarafından tanınmayan bir sürümü yüklüdür.
  • Cihazdaki teknik sorunlar

Cihaz geri çağırma (beta)

Ayrıca, cihaz hatırlama özelliğini etkinleştirebilirsiniz. Bu özellik, cihaz bazında bazı özel verileri belirli cihazlarda saklamanıza olanak tanır. Bu verileri, uygulamanız daha sonra aynı cihaza tekrar yüklendiğinde güvenilir bir şekilde alabilirsiniz. Bir bütünlük jetonu istedikten sonra, belirli bir cihaz için cihaz geri çağırma değerlerini değiştirmek üzere ayrı bir sunucudan sunucuya çağrı yaparsınız.

deviceRecall özelliğini etkinleştirirseniz deviceIntegrity alanında, belirli cihaz için ayarladığınız cihaz geri çağırma bilgileri yer alır:

"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 iki alana ayrılmıştır:

  • values: Bu cihaz için daha önce ayarladığınız bit değerlerini geri çağırın.
  • writeDates: Bit yazma tarihlerini yıl ve ay olarak doğru şekilde UTC'ye göre hatırlayın. Bir hatırlatma bitinin yazma tarihi, bit true olarak ayarlandığında her seferinde güncellenir ve bit false olarak ayarlandığında kaldırılır.

Cihaz geri çağırma bilgileri kullanılamadığında cihaz geri çağırma değeri boş olur:

"deviceIntegrity": {
  "deviceRecognitionVerdict": ["MEETS_DEVICE_INTEGRITY"],
  "deviceRecall": {
    "values": {},
    "writeDates": {}
  }
}

Hesap ayrıntıları alanı

accountDetails alanında, cihazda oturum açmış kullanıcı hesabı için uygulamanın Google Play lisanslama durumunu gösteren tek bir değer (appLicensingVerdict) bulunur. Kullanıcı hesabında uygulama için Play lisansı varsa kullanıcı, uygulamayı Google Play'den indirmiş veya satın almış demektir.

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

appLicensingVerdict aşağıdaki değerlerden birine sahip olabilir:

LICENSED
Kullanıcının uygulamadan yararlanma hakkı bulunmaktadır. Yani kullanıcı, uygulamanızı Google Play'den cihazına yüklemiş veya güncellemiştir.
UNLICENSED
Kullanıcının uygulamadan yararlanma hakkı yoktur. Kullanıcının uygulamanızı başka cihazdan yüklediği veya Google Play dışında bir kanaldan edindiği durumlarda bu etiket görülür. Bunu düzeltmek için kullanıcılara GET_LICENSED iletişim kutusunu gösterebilirsiniz.
UNEVALUATED

Koşullardan biri karşılanmadığı için lisanslama ayrıntıları değerlendirilmemiştir.

Bu durum aşağıdakiler dahil olmak üzere çeşitli nedenlerden kaynaklanabilir:

  • Cihaz yeterince güvenilir değildir.
  • Cihazda uygulamanızın Google Play tarafından tanınmayan bir sürümü yüklüdür.
  • Kullanıcı, Google Play'de oturum açmamıştır.

Kullanıcının uygulamanızdan yararlanma hakkına sahip olup olmadığını kontrol etmek için aşağıdaki kod snippet'inde gösterildiği gibi appLicensingVerdict değerinin beklendiği gibi olduğunu doğrulayın:

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

Ortam ayrıntıları alanı

Ortamla ilgili ek sinyalleri de etkinleştirebilirsiniz. Uygulama erişim riski; ekranı kaydetmek, yer paylaşımı görüntülemek veya cihazı kontrol etmek amacıyla başka uygulamaların çalıştırılıp çalıştırılmadığını uygulamanıza bildirir. Google Play Protect kararı, cihazda Google Play Protect'in etkinleştirilip etkinleştirilmediğini ve bilinen kötü amaçlı yazılım tespit edip etmediğini size bildirir.

Google Play Console'da uygulama erişimi riski kararı veya Play Protect kararını etkinleştirdiyseniz API yanıtınızda environmentDetails alanı bulunur. environmentDetails alanı iki değer içerebilir: appAccessRiskVerdict ve playProtectVerdict.

Uygulamaya erişim riski kararı

Etkinleştirildikten sonra Play Integrity API yükündeki environmentDetails alanında yeni uygulama erişim riski kararı görüntülenir.

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

Uygulama erişimi riski değerlendirildiyse appAccessRiskVerdict, bir veya daha fazla yanıt içeren alanı appsDetected içerir. Bu yanıtlar, algılanan uygulamaların yükleme kaynağına bağlı olarak aşağıdaki iki gruptan birine girer:

  • Play veya sistem uygulamaları: Google Play tarafından yüklenen veya cihaz üreticisi tarafından cihazın sistem bölümüne önceden yüklenen uygulamalar (FLAG_SYSTEM ile tanımlanır). Bu tür uygulamalarla ilgili yanıtların önüne KNOWN_ eklenir.

  • Diğer uygulamalar: Google Play tarafından yüklenmeyen uygulamalar. Bu, cihaz üreticisi tarafından sistem bölümüne önceden yüklenen uygulamaları kapsamaz. Bu tür uygulamalarla ilgili yanıtların başına UNKNOWN_ eklenir.

döndürülür.UNKNOWN_CAPTURING

Aşağıdaki yanıtlar döndürülebilir:

KNOWN_INSTALLED, UNKNOWN_INSTALLED
Yükleme kaynağıyla eşleşen uygulamalar yüklü olmalıdır.
KNOWN_CAPTURING, UNKNOWN_CAPTURING
Uygulamanız çalışırken ekranı görüntülemek için kullanılabilecek izinlerin etkinleştirildiği uygulamalar çalışıyor. Bu, cihazda çalışan ve Google Play tarafından bilinen doğrulanmış erişilebilirlik hizmetlerini hariç tutar.
KNOWN_CONTROLLING, UNKNOWN_CONTROLLING
Cihazı kontrol etmek ve uygulamanıza yapılan girişleri doğrudan kontrol etmek için kullanılabilecek izinlerin etkinleştirildiği uygulamalar çalışıyor. Bu uygulamalar, uygulamanızın giriş ve çıkışlarını yakalamak için de kullanılabilir. Bu durum, cihazda çalışan ve Google Play tarafından doğrulanmış erişilebilirlik hizmetlerini kapsamaz.
KNOWN_OVERLAYS, UNKNOWN_OVERLAYS
Uygulamanızda yer paylaşımları göstermek için kullanılabilecek izinlerin etkinleştirildiği uygulamalar çalışıyor. Bu, cihazda çalışan ve Google Play tarafından bilinen doğrulanmış erişilebilirlik hizmetlerini kapsamaz.
Boş (boş değer)

Koşullardan biri karşılanmadığı için uygulama erişimi riski değerlendirilmez. Bu durumda appAccessRiskVerdict alanı boş. Bu durum aşağıdakiler dahil olmak üzere çeşitli nedenlerden kaynaklanabilir:

  • Cihaz yeterince güvenilir değildir.
  • Cihazın form faktörü telefon, tablet veya katlanabilir cihaz değil.
  • Cihazda Android 6 (API düzeyi 23) veya daha yeni bir sürüm çalışmıyordur.
  • Cihazda uygulamanızın Google Play tarafından tanınmayan bir sürümü yüklüdür.
  • Cihazdaki Google Play Store sürümü güncel değildir.
  • Kullanıcı hesabında Play lisansı yok.
  • verdictOptOut parametresiyle standart bir istek kullanıldı.
  • Standart istekler için uygulama erişim riskini henüz desteklemeyen bir Play Integrity API kitaplığı sürümüyle standart istek kullanıldı.

Uygulama erişimi riski, geliştirilmiş bir Google Play erişilebilirlik incelemesinden geçmiş (cihazdaki herhangi bir uygulama mağazası tarafından yüklenmiş) doğrulanmış erişilebilirlik hizmetlerini otomatik olarak hariç tutar. "Hariç tutuldu", cihazda çalışan doğrulanmış erişilebilirlik hizmetlerinin, uygulama erişimi riski değerlendirmesinde yakalama, kontrol veya yer paylaşımı yanıtı döndürmeyeceği anlamına gelir. Erişilebilirlik uygulamanız için gelişmiş bir Google Play erişilebilirlik incelemesi talep etmek istiyorsanız uygulamanızı Google Play'de yayınlayın. Yayınlarken uygulamanızın manifest dosyasında isAccessibilityTool işaretinin true olarak ayarlandığından emin olun veya inceleme isteğinde bulunun.

Uygulamaya erişim riski kararı örnekleri

Aşağıdaki tabloda, uygulama erişimi risk kararlarına ve bunların ne anlama geldiğine dair bazı örnekler verilmiştir (bu tabloda olası tüm sonuçlar listelenmemiştir):

Uygulamaya erişim riski kararı için örnek yanıt Yorumlama
appsDetected:
["KNOWN_INSTALLED"]
Yalnızca Google Play tarafından tanınan veya cihaz üreticisi tarafından sistem bölümüne önceden yüklenmiş uygulamalar yüklüdür.
Kararların yakalanmasına, kontrol edilmesine veya yerleştirilmesine neden olacak uygulamalar çalışmıyordur.
appsDetected:
["KNOWN_INSTALLED",
"UNKNOWN_INSTALLED",
"UNKNOWN_CAPTURING"]
Google Play tarafından yüklenen veya cihaz üreticisi tarafından sistem bölümüne önceden yüklenen uygulamalar vardır.
Ekranı görüntülemek ya da diğer giriş ve çıkışları yakalamak için kullanılabilecek izinleri etkinleştirilmiş başka uygulamalar çalışıyordur.
appsDetected:
["KNOWN_INSTALLED",
"KNOWN_CAPTURING",
"UNKNOWN_INSTALLED",
"UNKNOWN_CONTROLLING"]
Ekranı görüntülemek veya diğer giriş ve çıkışları yakalamak için kullanılabilecek izinlerin etkinleştirildiği Play veya sistem uygulamaları çalışıyor.
Cihazı kontrol etmek ve uygulamanıza doğrudan girişleri kontrol etmek için kullanılabilecek, izinleri etkinleştirilmiş başka uygulamalar da çalışıyor.
appAccessRiskVerdict: {} Koşullardan biri karşılanmadığı için uygulama erişimi riski değerlendirilmemiştir. Örneğin, cihaz yeterince güvenilir olmayabilir.

Risk seviyenize bağlı olarak, devam etmek için hangi karar kombinasyonlarının kabul edilebilir olduğuna ve hangi kararlar için işlem yapmak istediğinize karar verebilirsiniz. Aşağıdaki kod snippet'inde, ekranı kaydedebilecek veya uygulamanızı kontrol edebilecek uygulamaların çalışmadığını doğrulama örneği gösterilmektedir:

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!
    }
}
Uygulamaya erişim riski kararlarını düzeltme

Risk seviyenize bağlı olarak, kullanıcının bir isteği veya işlemi tamamlamasına izin vermeden önce hangi uygulama erişimi risk kararlarıyla ilgili işlem yapmak istediğinize karar verebilirsiniz. Uygulama erişim riski sonucunu kontrol ettikten sonra kullanıcıya gösterebileceğiniz isteğe bağlı Google Play istemleri vardır. Uygulama erişim riski kararına neden olan bilinmeyen uygulamaları kapatmasını istemek için kullanıcıya CLOSE_UNKNOWN_ACCESS_RISK'i gösterebilir veya uygulama erişim riski kararına neden olan tüm uygulamaları (bilinen ve bilinmeyen) kapatmasını istemek için kullanıcıya CLOSE_ALL_ACCESS_RISK'i gösterebilirsiniz.

Play Protect kararı

Etkinleştirildikten sonra Play Integrity API yükündeki environmentDetails alanında Google Play Protect kararı görüntülenir:

"environmentDetails": {
  "playProtectVerdict": "NO_ISSUES"
}

playProtectVerdict aşağıdaki değerlerden birine sahip olabilir:

NO_ISSUES
Play Protect etkindir ve cihazda uygulama ile ilgili herhangi bir sorun tespit edilmemiştir.
NO_DATA
Play Protect etkindir ancak henüz tarama yapılmamıştır. Cihaz ya da Play Store uygulaması kısa süre önce sıfırlanmış olabilir.
POSSIBLE_RISK
Play Protect kapalıdır.
MEDIUM_RISK
Play Protect etkindir ve cihazda potansiyel zararlı uygulamaların yüklü olduğunu tespit etmiştir.
HIGH_RISK
Play Protect etkindir ve cihazda tehlikeli uygulamaların yüklü olduğunu tespit etmiştir.
UNEVALUATED

Play Protect kararı değerlendirilmemiştir.

Bu durum aşağıdakiler dahil olmak üzere çeşitli nedenlerden kaynaklanabilir:

  • Cihaz yeterince güvenilir değildir.
  • Kullanıcı hesabında Play lisansı yok.

Play Protect kararını kullanmayla ilgili kılavuz

Uygulamanızın arka uç sunucusu, risk toleransınıza göre karara bağlı olarak nasıl davranacağına karar verebilir. Aşağıda bazı öneriler ve olası kullanıcı işlemleri verilmiştir:

NO_ISSUES
Play Protect etkin ve herhangi bir sorun tespit etmedi. Bu nedenle kullanıcıların herhangi bir işlem yapması gerekmiyor.
POSSIBLE_RISK ve NO_DATA
Bu kararları aldığınızda kullanıcıdan Play Protect'in açık olup olmadığını ve tarama yapıp yapmadığını kontrol etmesini isteyin. NO_DATA yalnızca nadir durumlarda görünmelidir.
MEDIUM_RISK ve HIGH_RISK
Risk toleransınıza bağlı olarak, kullanıcıdan Play Protect'i başlatmasını ve Play Protect uyarılarıyla ilgili işlem yapmasını isteyebilirsiniz. Kullanıcı bu şartları karşılayamıyorsa sunucu işleminden engellenebilir.