בדף הזה מוסבר איך לפרש את תוצאת תקינות הנתונים שחוזרת ואיך להשתמש בה. בין ששולחים בקשה רגילה ל-API ובין ששולחים בקשה קלאסית ל-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
במטען הייעודי (payload) של ה-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. ... }
בבקשות 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
במטען הייעודי (payload) של 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 Services. המכשיר עובר את בדיקות התקינות של המערכת ועומד בדרישות התאימות של Android.
- ריק (ערך ריק)
- האפליקציה פועלת במכשיר שיש בו סימנים למתקפה (כמו הוק של API) או לפריצה למערכת (כמו גישה ל-root), או שהאפליקציה לא פועלת במכשיר פיזי (כמו אמולטור שלא עובר את בדיקות התקינות של 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 Games למחשב, השדה deviceRecognitionVerdict
יכול להכיל גם את התווית הבאה:
MEETS_VIRTUAL_INTEGRITY
- האפליקציה פועלת באמולטור שמבוסס על Android עם Google Play Services. האמולטור עובר את בדיקות התקינות של המערכת ועומד בדרישות התאימות הבסיסיות של Android.
מידע אופציונלי לגבי המכשיר
אם תבחרו לקבל תוויות נוספות בתוצאה של בדיקת תקינות הבחירות, הערך של deviceRecognitionVerdict
יכול לכלול את התוויות הנוספות הבאות:
MEETS_BASIC_INTEGRITY
- האפליקציה פועלת במכשיר שעובר את הבדיקות הבסיסיות של תקינות המערכת. יכול להיות שהמכשיר לא עומד בדרישות התאימות ל-Android, ויכול להיות שהוא לא אושר להריץ את Google Play Services. לדוגמה, יכול להיות שפועלת במכשיר גרסה לא מוכרת של Android, או שיש לו תוכנת אתחול לא נעולה, או שהוא לא אושר על ידי היצרן.
MEETS_STRONG_INTEGRITY
- האפליקציה פועלת במכשיר Android עם Google Play Services, ויש לה הוכחה חזקה לתקינות המערכת, כמו הוכחה לחתימה על התקינות של האתחול שמגובת בחומרה. המכשיר עובר את בדיקות התקינות של המערכת ועומד בדרישות התאימות של Android.
מכשיר יחיד יחזיר כמה תוויות של מכשיר בפסיקה לגבי תקינות המכשיר, אם הוא עומד בכל הקריטריונים של התווית.
פעילות במכשיר מהזמן האחרון
אפשר גם להביע הסכמה לקבלת אותות של פעילות במכשיר מהזמן האחרון, שמציינים כמה פעמים האפליקציה שלכם ביקשה טוקן תקינות במכשיר ספציפי בשעה האחרונה. אתם יכולים להשתמש בפעילות מהזמן האחרון במכשיר כדי להגן על האפליקציה מפני מכשירי היפר-פעילות לא צפויים, שיכולים להעיד על מתקפה פעילה. אתם יכולים לקבוע את מידת האמון בכל רמה של פעילות במכשיר מהזמן האחרון על סמך מספר הפעמים שאתם מצפים שהאפליקציה שמותקנת במכשיר טיפוסי תבקש טוקן תקינות בכל שעה.
אם תבחרו לקבל את 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 |
לא בוצעה הערכה של הפעילות במכשיר מהזמן האחרון. הסיבות לכך יכולות להיות:
|
השדה 'פרטי החשבון'
השדה 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! }
השדה Environment details
אפשר גם להביע הסכמה לשימוש באותות נוספים לגבי הסביבה. האות 'סיכון לגישה לאפליקציה' מאפשר לאפליקציה לבדוק אם יש אפליקציות פועלות אחרות שיכולות לצלם את המסך, להציג שכבות-על או לשלוט במכשיר. לפי קביעת Play Protect אפשר לדעת אם Google Play Protect מופעל במכשיר ואם הוא זיהה תוכנות זדוניות מוכרות.
אם הבעתם הסכמה לקביעה של סיכון הגישה לאפליקציה או לקביעה של Play Protect ב-Google Play Console, תגובת ה-API תכלול את השדה 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 (רמת API 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 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. אם המשתמש לא יכול למלא את הדרישות האלה, אתם יכולים לחסום אותו מפעולת השרת.