بيانات السلامة

وتصف هذه الصفحة كيفية تفسير السلامة التي تم إرجاعها والعمل عليها القرار. وسواء أجريت طلبًا عاديًا أو كلاسيكيًا من واجهة برمجة التطبيقات، فإن التكامل البيانات بالتنسيق نفسه مع محتوى مشابه. السلامة بيان الجهاز ينقل معلومات حول سلامة الأجهزة والتطبيقات الحسابات. يمكن لخادم تطبيقك استخدام الحمولة الناتجة في ملف تم فك تشفيره، بيان معتمد لتحديد أفضل السبل للمضي قدمًا في إجراء معين أو في تطبيقك.

تنسيق بيان السلامة الذي تم إرجاعه

البيانات الأساسية هي بتنسيق JSON العادي وتحتوي على إشارات سلامة إلى جانب المعلومات التي يقدّمها المطوّر

في ما يلي بنية الحمولة العامة:

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

يجب التحقّق أولاً من تطابق القيم في الحقل requestDetails مع تلك القيم للطلب الأصلي قبل التحقق من كل بيان سلامة. ما يلي: الأقسام بشكل أكثر تفصيلاً كل حقل.

حقل تفاصيل الطلب

يحتوي الحقل requestDetails على معلومات عن الطلب، بما في ذلك المعلومات التي قدّمها المطوّر في requestHash للطلبات العادية nonce للطلبات الكلاسيكية.

بالنسبة إلى طلبات البيانات من واجهة برمجة التطبيقات العادية:

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 مع ما تم إرساله في النسخة الأصلية. كما هو موضح في مقتطف الرمز التالي:

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

بالنسبة إلى طلبات البيانات من واجهة برمجة التطبيقات الكلاسيكية:

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 مع ما تم إرساله في الطلب الأصلي، حيث كما هو موضح في مقتطف الرمز التالي:

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

حقل سلامة التطبيق

يتضمّن الحقل 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
لم يتم تقييم سلامة التطبيق. شرط ضروري قد يكون تم إغفاله، مثلاً أن يكون الجهاز غير موثوق بالقدر الكافي.

للتأكّد من أنّ الرمز المميّز تمّ إنشاؤه من خلال تطبيق أنشأته، عليك إثبات ملكيته. من أن سلامة التطبيق على النحو المتوقع، كما هو موضح في التعليمات البرمجية التالية snippet:

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

يمكنك أيضًا التحقّق من اسم حزمة التطبيق وإصدار التطبيق وشهادات التطبيق. يدويًا.

حقل سلامة الجهاز

يمكن أن يحتوي الحقل deviceIntegrity على قيمة واحدة، deviceRecognitionVerdict، التي تحتوي على تصنيف واحد أو أكثر يمثل مدى جهازك فرض سلامة التطبيق. إذا كان الجهاز لا يفي بمعايير أيٍ من التصنيفات، يكون الحقل deviceIntegrity فارغًا.

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

بشكل تلقائي، يمكن أن يحتوي deviceRecognitionVerdict على ما يلي:

MEETS_DEVICE_INTEGRITY
يعمل التطبيق على جهاز يعمل بنظام التشغيل Android ويحتوي على خدمات Google Play يجتاز الجهاز عمليات التأكّد من سلامة النظام ويفي بالغرض. متطلبات التوافق مع Android.
حقل فارغ (قيمة فارغة)
يعمل التطبيق على جهاز يتضمّن علامات. هجوم (مثل اعتراض طلبات البيانات من واجهة برمجة التطبيقات) أو اختراق النظام (مثل الوصول إلى الجذر) لا يعمل التطبيق على أي جهاز فعلي (مثل المحاكي الذي عدم اجتياز عمليات التحقّق من السلامة في Google Play).

للتأكّد من أنّ الرمز المميّز مصدره جهاز موثوق به، تحقَّق من deviceRecognitionVerdict كما هو متوقع، كما هو موضح في الرمز التالي snippet:

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

إذا كنت تواجه مشاكل في جهاز الاختبار الذي يستوفي سلامة الجهاز، التأكد من تثبيت ذاكرة القراءة فقط على الإعدادات الأصلية (على سبيل المثال، من خلال إعادة ضبط الجهاز) وأن برنامج الإقلاع مقفَل. يمكنك أيضًا إنشاء اختبارات واجهة برمجة التطبيقات Play Integrity API. في Play Console

تصنيفات الأجهزة الشرطية

إذا كان تطبيقك يتم طرحه على "ألعاب Google Play" على الكمبيوتر، يمكن أن يحتوي deviceRecognitionVerdict أيضًا على التصنيف التالي:

MEETS_VIRTUAL_INTEGRITY
يعمل التطبيق على محاكي يعمل بنظام Android وفيه خدمات Google Play يجتاز المحاكي عمليات التحقق من سلامة النظام ويلتزم متطلبات التوافق الأساسية مع Android.

معلومات اختيارية عن الجهاز

في حال الموافقة على تلقّي التصنيفات في بيان السلامة، يمكن أن يحتوي deviceRecognitionVerdict على التصنيفات الإضافية التالية:

MEETS_BASIC_INTEGRITY
يعمل التطبيق على جهاز يمر بوظائف أساسية. عمليات فحص سلامة النظام. قد لا يتوافق الجهاز مع نظام التشغيل Android. المتطلبات وقد لا تتم الموافقة على تشغيل خدمات Google Play. بالنسبة على سبيل المثال، قد يعمل الجهاز بإصدار غير معروف من نظام التشغيل Android، وقد تحتوي على برنامج إقلاع تم فتح قفله، أو ربما لم تعتمدها الشركة المصنعة.
MEETS_STRONG_INTEGRITY
يعمل التطبيق على جهاز يعمل بنظام التشغيل Android ويحتوي على توفّر "خدمات Google Play" ضمانًا قويًا لسلامة النظام، مثل دليل مستند إلى الأجهزة لسلامة التمهيد. يجتاز الجهاز النظام يتحقّق من السلامة ويفي بمتطلبات التوافق مع Android.

سيعرض جهاز واحد تصنيفات أجهزة متعددة ضمن سلامة الجهاز ما إذا تم استيفاء كل معيار من معايير التصنيف.

أحدث نشاط للجهاز

يمكنك أيضًا الموافقة على الأنشطة الحديثة على الجهاز التي تخبرك بكيفية عدد المرات التي طلب فيها تطبيقك رمزًا مميّزًا للسلامة على جهاز معيّن خلال الساعة الماضية. يمكنك استخدام الأنشطة الحديثة على الجهاز لحماية تطبيقك من الأجهزة الفائقة النشاط غير المتوقعة التي قد تكون مؤشرًا على هجوم نشط. يمكنك تحديد مقدار الثقة في كل مستوى نشاط حديث على الجهاز بناءً على مدى تتوقّع كثيرًا أن يطلب تطبيقك المثبَّت على أحد الأجهزة العادية تكامل البيانات كل ساعة.

في حال الموافقة على تلقّي recentDeviceActivity الحقل deviceIntegrity سيكون له قيمتان:

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

يختلف تعريفات deviceActivityLevel بين الوضعين ويمكن أن يكون يتم عرض إحدى القيم التالية:

مستوى النشاط الأخير للجهاز طلبات الرموز المميّزة العادية لسلامة واجهة برمجة التطبيقات على هذا الجهاز خلال الساعة الأخيرة لكل تطبيق طلبات الرموز المميّزة الكلاسيكية لسلامة واجهة برمجة التطبيقات على هذا الجهاز خلال الساعة الأخيرة لكل تطبيق
LEVEL_1 (الأدنى) 10 أو أقل 5 أو أقل
LEVEL_2 بين 11 و25 بين 6 و10
LEVEL_3 بين 26 و50 بين 11 و15
LEVEL_4 (الأعلى) أكثر من 50 أكثر من 15
UNEVALUATED لم يتم تقييم أنشطة الجهاز الأخيرة. قد يحدث هذا الأمر للأسباب التالية:
  • الجهاز غير موثوق بالقدر الكافي
  • لم يتعرّف Google على إصدار التطبيق المثبّت على الجهاز اللعب.
  • وجود مشاكل فنية في الجهاز

حقل تفاصيل الحساب

يحتوي الحقل 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 على إصدار التطبيق المثبّت على الجهاز اللعب.
  • لم يسجّل المستخدم الدخول إلى Google Play.

للتأكّد من أنّ المستخدم لديه إذن الوصول إلى تطبيقك، عليك التأكّد من أنّ appLicensingVerdict كما هو متوقع، كما هو موضح في مقتطف الرمز التالي:

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

حقل تفاصيل البيئة

ويمكنك أيضًا تفعيل إشارات إضافية عن البيئة. الوصول إلى التطبيق في حالة وجود أي تطبيقات أخرى قيد التشغيل يمكن استخدامها أو تصوير الشاشة أو عرض العناصر المركّبة أو التحكم في الجهاز Play للحماية يخبرك البيان ما إذا تم تفعيل "Google Play للحماية" على الجهاز وما إذا اكتشف برامج ضارة معروفة.

في حال الموافقة على بيان "مخاطر الوصول إلى التطبيق" أو بيان "Play للحماية" في Google Play Console، سيتضمّن ردّ واجهة برمجة التطبيقات الحقل "environmentDetails". يمكن أن يحتوي الحقل environmentDetails على اثنين القيمتين appAccessRiskVerdict وplayProtectVerdict.

بيان خطورة الوصول إلى التطبيق (إصدار تجريبي)

بعد تفعيل الميزة، سيتم ملء الحقل "environmentDetails" في Play Integrity API. الحمولة ستحتوي على بالبيان الجديد حول خطورة الوصول إلى التطبيق.

{
  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 التي يتم تشغيلها على الجهاز
EMPTY (قيمة فارغة)

لا يتم تقييم مخاطر الوصول إلى التطبيق في حال عدم استيفاء أحد المتطلّبات الضرورية. ضِمن في هذه الحالة، يكون الحقل appAccessRiskVerdict فارغًا. يمكن أن يحدث هذا لعدة أسباب، منها ما يلي:

  • الجهاز غير موثوق بالقدر الكافي
  • شكل الجهاز ليس هاتفًا أو جهازًا لوحيًا أو هاتفًا قابلاً للطيّ.
  • لا يعمل الجهاز بنظام التشغيل Android 6 (المستوى 23 لواجهة برمجة التطبيقات) أو بإصدار أحدث.
  • لا يتعرّف Google Play على إصدار التطبيق المثبّت على الجهاز
  • إصدار "متجر Google Play" المثبَّت على الجهاز قديم.
  • الألعاب فقط: لا يملك حساب المستخدم ترخيص Play للعبة.
  • تم استخدام طلب عادي مع معلَمة verdictOptOut.
  • تم استخدام طلب عادي مع إصدار مكتبة واجهة برمجة التطبيقات Play Integrity API. التي لا تتيح بعد إمكانية وصول المستخدمين إلى التطبيق في عمليات الطلب العادية

تستبعد ميزة "مخاطر الوصول إلى التطبيق" تلقائيًا خدمات تسهيل الاستخدام التي تم التحقّق منها والتي قد تم إجراء مراجعة محسَّنة لإمكانية الوصول في Google Play (تم تثبيتها بواسطة أي متجر تطبيقات على الجهاز). "مستبعد" يعني أن إمكانية الوصول المعتمدة الخدمات التي تعمل على الجهاز لن تعرض عملية الالتقاط أو التحكم أو استجابة العناصر المركّبة في بيان خطورة الوصول إلى التطبيق لطلب حساب محسّن من Google تشغيل مراجعة تسهيل الاستخدام الخاصة بتطبيق تسهيل الاستخدام، ونشره على Google عليك التأكّد من ضبط العلامة isAccessibilityTool على "صحيح" في تطبيقك. في بيان تطبيقك أو طلب إجراء مراجعة.

يقدم الجدول التالي بعض الأمثلة على القرارات وما تعنيه (هذا كل النتائج المحتملة):

مثال على الاستجابة لبيان خطورة الوصول إلى التطبيق التفسير
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: {} لا يتم تقييم خطورة الوصول إلى التطبيق بسبب عدم استيفاء أحد المتطلّبات الضرورية. على سبيل المثال، لم يكن الجهاز جديرًا بالثقة بما يكفي.

بناءً على مستوى المخاطر، يمكنك تحديد مجموعة البيانات التي الموافقة على المتابعة والبيانات التي تريد اتخاذ إجراء بشأنها. تشير رسالة الأشكال البيانية مقتطف الرمز التالي مثالاً على التحقق من عدم وجود التطبيقات قيد التشغيل التي يمكن أن تلتقط الشاشة أو تتحكّم في تطبيقك:

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!
    }
}
معالجة بيانات خطورة الوصول إلى التطبيق

بناءً على مستوى المخاطر لديك، يمكنك تحديد بيانات خطورة الوصول إلى التطبيق. تريد اتخاذ إجراء بشأنها قبل السماح للمستخدم بإكمال طلب أو إجراء. هناك طلبات اختيارية من Google Play يمكنك عرضها للمستخدم بعد التحقق من بيان خطورة الوصول إلى التطبيق. يمكنك عرض CLOSE_UNKNOWN_ACCESS_RISK لتطلب من المستخدم إغلاق التطبيقات غير المعروفة التي تتسبب في بيان خطورة الوصول إلى التطبيق أو يمكنك عرض CLOSE_ALL_ACCESS_RISK لطلب إغلاق المستخدم لجميع التطبيقات (المعروفة وغير المعروفة) التي تؤدي إلى ظهور بيان خطر الوصول إلى التطبيق

بيان "Play للحماية"

بعد تفعيل الميزة، سيتم ملء الحقل "environmentDetails" في Play Integrity API. الحمولة ستحتوي على بيان "Play للحماية":

environmentDetails: {
  playProtectVerdict: "NO_ISSUES"
}

يمكن أن تحتوي playProtectVerdict على إحدى القيم التالية:

NO_ISSUES
تم تفعيل خدمة "Play للحماية" ولم يتم رصد أي مشاكل في التطبيق على الجهاز.
NO_DATA
تم تفعيل "Play للحماية" ولكن لم يتم إجراء أي فحص بعد. الجهاز أو فربما يكون قد تمت إعادة ضبط تطبيق "متجر Play" مؤخرًا.
POSSIBLE_RISK
تم إيقاف "Play للحماية".
MEDIUM_RISK
تم تفعيل خدمة "Play للحماية" وتم تثبيت تطبيقات قد تتسبّب بضرر. على الجهاز
HIGH_RISK
تم تفعيل خدمة "Play للحماية" وعثرت على تطبيقات خطيرة تم تثبيتها على جهازك.
UNEVALUATED

لم يتم تقييم بيان "Play للحماية".

وقد يحدث ذلك لعدة أسباب، بما فيها ما يلي:

  • الجهاز غير موثوق بالقدر الكافي
  • الألعاب فقط: لا يملك حساب المستخدم ترخيص Play لهذه اللعبة.

إرشادات حول استخدام بيان "Play للحماية"

يمكن لخادم الخلفية في تطبيقك تحديد كيفية التصرف بناءً على القرار استنادًا إلى وقدرتك على تحمل المخاطر. في ما يلي بعض الاقتراحات والإجراءات المحتملة للمستخدمين:

NO_ISSUES
تم تفعيل خدمة "Play للحماية" ولم ترصد أي مشاكل، لذا ليس عليك اتّخاذ أي إجراء من قِبل المستخدم.
POSSIBLE_RISK وNO_DATA
عند تلقّي هذه البيانات، اطلب من المستخدم التأكد من تفعيل "Play للحماية". وتم إجراء فحص له. من المفترض أن تظهر NO_DATA في حالات نادرة فقط.
MEDIUM_RISK وHIGH_RISK
بناءً على تحمُّلك للمخاطر، يمكنك أن تطلب من المستخدم تشغيل Google Play الحماية واتّخاذ إجراء بشأن تحذيرات "Play للحماية" إذا لم يتمكن المستخدم من ملء هذه المتطلبات، فيمكنك منعهم من تنفيذ إجراء الخادم.