توضّح هذه الصفحة كيفية تفسير نتيجة INTEGRITY المعروضة وكيفية التعامل معها. سواء أكنت تُجري طلبًا عاديًا أو كلاسيكيًا من واجهة برمجة التطبيقات، يتم عرض نتيجة السلامة بالتنسيق نفسه وبمحتوى مشابه. يعرض بيان السلامة معلومات عن صلاحية الأجهزة والتطبيقات والحسابات. يمكن لخادم تطبيقك استخدام الحمولة الناتجة في بيان سلامة مفعَّل التشفير ومُثبَّت صحته لتحديد أفضل طريقة لمتابعة إجراء معيّن أو طلب معيّن في تطبيقك.
تنسيق بيان السلامة الذي يتم إرجاعه
الحمولة هي نص 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
- لم يتم تقييم سلامة التطبيق. ولم يتم استيفاء أحد المتطلّبات الضرورية، مثلاً أن يكون الجهاز غير موثوق بالقدر الكافي.
للتأكّد من أنّ الرمز المميّز قد تم إنشاؤه بواسطة تطبيق أنشأته، عليك التحقّق مما يلي: أنّ سلامة التطبيق على النحو المتوقّع، كما هو موضّح في مقتطف الرمز المميّز التالي:
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
كما هو متوقّع، كما هو موضّح في مقتطف الرمز التالي:
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! }
إذا كنت تواجه مشاكل في جهاز الاختبار تتعلق بسلامة الجهاز، تأكَّد من تثبيت نظام التشغيل الثابت (ROM) من المصنع (على سبيل المثال، من خلال إعادة ضبط الجهاز) ومن قفل أداة تحميل البرامج. يمكنك أيضًا إنشاء اختبارات 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 |
لم يتم تقييم أحدث نشاط للجهاز. قد يحدث ذلك
للأسباب التالية:
|
سمات الجهاز
يمكنك أيضًا تفعيل سمات الجهاز التي تُعلم إصدار حزمة تطوير البرامج (SDK) لنظام التشغيل Android بنظام التشغيل Android الذي يعمل على الجهاز. وقد تتم إضافة سمات أخرى للأجهزة في المستقبل.
قيمة إصدار حزمة SDK هي رقم إصدار حزمة SDK لنظام التشغيل Android المحدَّد في
Build.VERSION_CODES
. لا يتم تقييم إصدار حزمة تطوير البرامج (SDK)
في حال عدم استيفاء أحد المتطلّبات الضرورية. في هذه الحالة،
لم يتم ضبط الحقل sdkVersion
، وبالتالي يكون الحقل deviceAttributes
فارغًا.
قد يرجع سبب ذلك إلى:
- الجهاز غير موثوق بالقدر الكافي
- لا يتعرّف Google Play على إصدار تطبيقك المثبّت على الجهاز.
- حدثت مشاكل فنية على الجهاز.
إذا وافقت على تلقّي 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. }
حقل تفاصيل الحساب
يحتوي الحقل 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
كما هو متوقّع، كما هو موضّح في مقتطف الرمز التالي:
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! }
حقل تفاصيل البيئة
يمكنك أيضًا تفعيل إشارات إضافية عن البيئة. تُعلم ميزة "احتمالية الوصول إلى التطبيق" تطبيقك إذا كانت هناك تطبيقات أخرى قيد التشغيل يمكن استخدامها لالتقاط لقطات للشاشة أو عرض محتوى على السطح أو التحكّم في الجهاز. يوضّح بيان "Google 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 بأنّها تعمل على الجهاز.
- فارغ (قيمة فارغة)
لا يتم تقييم احتمالية اختراق التطبيق في حال عدم استيفاء أحد المتطلّبات الضرورية. في هذه الحالة، يكون حقل
appAccessRiskVerdict
فارغًا. وقد يحدث ذلك لعدة أسباب، بما في ذلك:- الجهاز غير موثوق بالقدر الكافي
- شكل الجهاز ليس هاتفًا أو جهازًا لوحيًا أو جهازًا قابلاً للطي.
- الجهاز لا يعمل بالإصدار 6 من نظام التشغيل Android (المستوى 23 من واجهة برمجة التطبيقات) أو إصدار أحدث.
- لا يتعرّف Google Play على إصدار التطبيق المثبّت على الجهاز
- إذا كان إصدار "متجر Google Play" على الجهاز قديمًا
- الألعاب فقط: لا يملك حساب المستخدم ترخيصًا على 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: {}
|
لم يتم تقييم مخاطر الوصول إلى التطبيق بسبب عدم استيفاء أحد المتطلّبات الضرورية. على سبيل المثال، كان الجهاز غير موثوق به بالقدر الكافي. |
استنادًا إلى مستوى المخاطر، يمكنك تحديد مجموعة الأحكام المقبولة للمتابعة والأحكام التي تريد اتّخاذ إجراء بشأنها. يوضّح مقتطف الرمز البرمجي التالي مثالاً على التحقّق من عدم وجود تطبيقات قيد التشغيل يمكنها أخذ لقطات للشاشة أو التحكّم في تطبيقك:
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 Protect:
environmentDetails: {
playProtectVerdict: "NO_ISSUES"
}
يمكن أن يكون playProtectVerdict
إحدى القيم التالية:
NO_ISSUES
- تم تفعيل خدمة "Play للحماية" ولم تعثر على أي مشاكل في التطبيقات على الجهاز.
NO_DATA
- تم تفعيل خدمة "Play للحماية" ولكن لم يتم إجراء أي عملية فحص حتى الآن. قد تكون تمت إعادة ضبط الجهاز أو تطبيق "متجر Play" مؤخرًا.
POSSIBLE_RISK
- تم إيقاف خدمة "Play للحماية":
MEDIUM_RISK
- تم تفعيل خدمة "Play للحماية" وعثرت على تطبيقات قد تتسبّب بضرر مثبّتة على الجهاز.
HIGH_RISK
- تكون خدمة "Play للحماية" مفعّلة وقد عثرت على تطبيقات خطيرة مثبّتة على الجهاز.
UNEVALUATED
لم يتم تقييم قرار "Google Play للحماية".
وقد يحدث ذلك لعدة أسباب، بما فيها ما يلي:
- الجهاز غير موثوق بالقدر الكافي
- الألعاب فقط: لا يملك حساب المستخدم ترخيصًا على Play للّعبة.
إرشادات حول استخدام قرار "Play للحماية"
يمكن لخادم الخلفية في تطبيقك أن يقرّر كيفية التصرف استنادًا إلى بيان السلامة استنادًا إلى مستوى تحملك للمخاطر. في ما يلي بعض الاقتراحات وإجراءات المستخدمين المحتمَلة:
NO_ISSUES
- تم تفعيل خدمة "Google Play للحماية" ولم يتم العثور على أي مشاكل، لذا ليس على المستخدم اتّخاذ أي إجراء.
POSSIBLE_RISK
وNO_DATA
- عند تلقّي هذه الأحكام، اطلب من المستخدم التحقّق من تفعيل خدمة "Play للحماية"
وإجراء فحص. من المفترض ألا يظهر الرمز
NO_DATA
إلا في حالات نادرة. MEDIUM_RISK
وHIGH_RISK
- استنادًا إلى مستوى المخاطر المقبولة لديك، يمكنك أن تطلب من المستخدم تشغيل "Play الحماية" واتّخاذ إجراء بشأن تحذيرات "Play للحماية". إذا لم يتمكّن المستخدم من استيفاء هذه المتطلبات، يمكنك حظره من إجراء الخادم.