סימוכין לרישוי

מחלקות וממשקים של LVL

בטבלה 1 מפורטים כל קובצי המקור בתהליך אימות הרישיון ספרייה (LVL) זמינה דרך Android SDK. כל הקבצים הם חלק מ- החבילה com.android.vending.licensing.

טבלה 1. סיכום של ספריית LVL סיווגים וממשקים.

קטגוריה שם תיאור
בדיקת הרישיון והתוצאה הכלי LicenseCheck מחלקה שאתם יוצרים (או מחלקה משנית) כדי להתחיל בדיקת רישיון.
LicenseCheckerCallback הממשק שמטמיעים כדי לטפל בתוצאות של בדיקת הרישיון.
מדיניות מדיניות הממשק שאתם מטמיעים כדי לקבוע אם לאפשר גישה לאפליקציה, בהתאם לתגובת הרישיון.
מדיניות מנוהלת של Server הטמעת ברירת מחדל של Policy. נעשה שימוש בהגדרות שנקבעו על ידי שרת רישוי לניהול אחסון מקומי של נתוני רישיון, תוקף הרישיון, לנסות שוב.
מדיניות מחמירה הטמעה חלופית של Policy. אוכפת רישוי על סמך את תגובת הרישיון מהשרת בלבד. אין שמירה במטמון או בקשה חוזרת.
ערפול נתונים (obfuscation)
(אופציונלי)
מעורפל (obfuscator) הממשק שמטמיעים אם משתמשים ב-Policy (כמו ServermanagedPolicy) ששומר במטמון את נתוני התגובות לרישיון במאגר קבוע. הפעלת אלגוריתם ערפול קוד (obfuscation) כדי לקודד ולפענח נתונים בכתיבה או נקראו.
AESObfuscator הטמעת ברירת מחדל של ערפול קוד (obfuscator) שמשתמשת בהצפנה/פענוח של AES לערפול קוד (obfuscation) של נתונים.
הגבלת מכשירים
(אופציונלי)
DeviceLimiter הממשק שמטמיעים אם רוצים להגביל את השימוש אפליקציה ספציפית למכשיר מסוים. התקשרת מ- LicenseValidator. הטמעה DeviceLimiter לא מומלץ עבור רוב האפליקציות כי הוא דורש שרת עורפי שעלול לגרום למשתמש לאבד את הגישה לאפליקציות ברישיון, אלא אם הוא מתוכנן בקפידה.
NullDeviceLimiter הטמעת ברירת המחדל של DeviceLimiter באופן שאינו תפעול (מאפשרת גישה לכל הפריטים מכשירים).
ליבת הספרייה, אין צורך בשילוב נתוני תגובה מחלקה שמכילה את השדות של תגובת רישיון.
מאמת רישיונות כיתה מפענחת ומאמתת תשובה שהתקבלה מרישוי השרת.
חריגת אימות סיווג שמציין שגיאות שמתרחשות במהלך אימות תקינות הנתונים שמנוהלות על ידי ערפול קוד (obfuscator).
מעורפל העדפות סיווג שירות שכותב/קורא נתונים מעורפלים (obfuscated) חנות אחת (SharedPreferences).
ILicensingService ממשק IPC חד-כיווני שבו מועברת בקשה לבדיקת רישיון אל לקוח Google Play.
Iרישיון תוצאהListener הטמעת קריאה חוזרת (callback) של IPC חד-כיוונית שבאמצעותה האפליקציה מקבלת תגובה אסינכרונית משרת הרישוי.

תגובת השרת

בטבלה 2 מפורטים כל שדות התגובה לרישיון שהוחזרו על ידי שרת רישוי.

טבלה 2. סיכום שדות התגובה לרישיונות שהוחזר על ידי שרת Google Play.

שדה תיאור
responseCode קוד התגובה שהוחזר על ידי שרת הרישוי. קודי התגובה הם שמתוארת בקודי תגובה של השרת.
signedData שרשור מחרוזת שכולל את הנתונים שהוחזרו על ידי שרת הרישוי באופן הבא: responseCode|nonce|packageName|versionCode|userId|timestamp:extras
  • responseCode: קוד התגובה שהוחזר על ידי שרת הרישוי.
  • nonce: מזהה הצופן של הבקשה.
  • packageName: שם החבילה של האפליקציה שצריך לבדוק את הרישיון עבורה.
  • versionCode: קוד הגרסה של האפליקציה שצריך לבדוק את הרישיון.
  • userId: מזהה ייחודי של המשתמש בכל אפליקציה, שבו אותו משתמש מקבל למזהה אחר לאפליקציה אחרת.
  • timestamp: מספר אלפיות השנייה מתחילת התקופה של 1970-01-01 00:00:00 UTC לשליחת הבקשה.
  • extras: מידע נוסף שיעזור לכם בניהול הרישיונות של האפליקציה. השדות הנוספים מפורטים תוספות לתגובת שרת.
signature החתימה של signedData באמצעות מפתח ספציפי לאפליקציה.

קודי תגובה של השרת

בטבלה 3 מפורטים כל קודי התגובה של הרישיונות שנתמכים על ידי שרת רישוי. באופן כללי, אפליקציה צריכה לטפל בכל התגובות האלה קודים. כברירת מחדל, המחלקה LicenseValidator ב-LVL מספקת את כל לטיפול הדרוש בקודי התגובה האלה.

טבלה 3. סיכום של קודי התגובה שהוחזר על ידי שרת Google Play בתגובה לרישיון.

קוד תגובה ייצוג של מספר שלם תיאור חתום? תוספות תגובות
LICENSED 0 האפליקציה קיבלה רישיון למשתמש. המשתמש רכש את מורשה להוריד ולהתקין את גרסת אלפא או הבטא של האפליקציה. כן VTGT, GR מתן גישה בהתאם למגבלות של Policy.
LICENSED_OLD_KEY 2 האפליקציה קיבלה רישיון למשתמש, אבל יש אפליקציה מעודכנת גרסה זמינה שחתומה באמצעות מפתח אחר. כן VT, GT, GR, UT אופציונלי: אפשר גישה בהתאם למגבלות Policy.

יכול לציין שזוג המפתחות שמשמש את גרסת האפליקציה לא חוקית או שהיא נפגעה. האפליקציה יכולה לאפשר גישה במקרה הצורך או הודעה למשתמש שיש שדרוג זמין, והגבלת השימוש הנוסף עד לשדרוג.

NOT_LICENSED 1 למשתמש אין רישיון לאפליקציה. לא לא לאפשר גישה.
ERROR_CONTACTING_SERVER 257 שגיאה מקומית — אפליקציית Google Play לא הצליחה להגיע אל שרת רישוי, כנראה בגלל בעיות בזמינות הרשת. לא ניסיון חוזר של בדיקת הרישיון בהתאם למגבלות של Policy ניסיונות חוזרים.
ERROR_SERVER_FAILURE 4 שגיאה בחיבור לשרת — השרת לא הצליח לטעון את מפתח האפליקציה לרישוי. לא ניסיון חוזר של בדיקת הרישיון בהתאם למגבלות של Policy ניסיונות חוזרים.
ERROR_INVALID_PACKAGE_NAME 258 שגיאה מקומית – האפליקציה ביקשה בדיקת רישיון לחבילה שלא מותקנת במכשיר. לא אין לנסות שוב לבצע את בדיקת הרישיון.

בדרך כלל נגרמה בגלל שגיאת פיתוח.

ERROR_NON_MATCHING_UID 259 שגיאה מקומית – האפליקציה ביקשה בדיקת רישיון לחבילה שה-UID (חבילה, צמד מזהה המשתמש) לא תואם לזה של הבקשה תרגום מכונה. לא אין לנסות שוב לבצע את בדיקת הרישיון.

בדרך כלל נגרמה בגלל שגיאת פיתוח.

ERROR_NOT_MARKET_MANAGED 3 שגיאת שרת — האפליקציה (שם החבילה) לא זוהה על ידי Google Play. לא אין לנסות שוב לבצע את בדיקת הרישיון.

יכול לציין שהאפליקציה לא פורסמה דרך Google Play או שיש שגיאת פיתוח ברישוי יישום בפועל.

הערה: כפי שמתועד ב- מגדירים את סביבת הבדיקה, אפשר לשלוח את קוד התגובה באופן ידני בוטלה עבור מפתח האפליקציה וכל משתמש מבחן רשום באמצעות Google Play Console.

הערה: בעבר אפשר היה לבדוק אפליקציה לפי העלאת "טיוטה" שלא פורסמה . הפונקציונליות הזו כבר לא בתוקף נתמך; במקום זאת, צריך לפרסם אותה בהפצת אלפא או בטא. . למידע נוסף, ראו טיוטות של אפליקציות התמיכה בהם הופסקה.

תוספות לתגובת השרת

לעזור לאפליקציה בניהול הגישה לאפליקציה במסגרת ההחזר הכספי על האפליקציה ולספק מידע נוסף, שרת הרישוי כולל מספר חלקים בתגובות לרישיונות. באופן ספציפי, השירות מספק ערכים מומלצים עבור תקופת תוקף הרישיון של הבקשה, תקופת החסד של ניסיון חוזר, מספר הניסיונות המקסימלי המותר ועוד הגדרות. אם האפליקציה משתמשת ב-APK קובצי הרחבות, התגובה כוללת גם את שמות הקבצים, הגדלים וכתובות ה-URL שלהם. השרת מצרף את ההגדרות בתור צמדי מפתח-ערך בתגובת הרישיון 'extras' השדה הזה.

כל הטמעה של Policy יכולה לחלץ את הגדרות התוספות מהרישיון ולהשתמש בהם לפי הצורך. הטמעת ברירת המחדל של Policy LVL, ServerManagedPolicy, משמשת כשכבת-על ואיור שבו מוסבר איך להשיג, לאחסן ולהשתמש הגדרות.

טבלה 4. סיכום של הגדרות ניהול הרישיונות שסופקו על ידי שרת Google Play ברישיון תשובה.

נוסףתיאור
VT חותמת הזמן של תוקף הרישיון. מציין את התאריך/השעה שבהם ההגדרה הנוכחית פג התוקף של תגובת הרישיון (שמורה במטמון) וצריך לבדוק אותה מחדש בשרת הרישוי. לעיון בקטע בהמשך בנושא תקופת תוקף הרישיון.
GT חותמת הזמן של תקופת החסד. מציין את סיום התקופה שבה המדיניות עשויה לאפשר גישה לאפליקציה, למרות שסטטוס התגובה RETRY

הערך מנוהל על ידי השרת, אבל ערך טיפוסי הוא 5 או יותר ימים. לעיון בקטע שבהמשך לגבי תקופת ניסיון חוזר ומספר הניסיונות המקסימלי.

GR מספר הניסיונות החוזרים המקסימלי. שדה זה מציין כמה בדיקות רצופות של רישיונות RETRY Policy צריך לאפשר, לפני ביטול גישת המשתמש לאפליקציה.

הערך מנוהל על ידי השרת, אבל ערך טיפוסי הוא '10' או גבוהה יותר. לעיון בקטע שבהמשך לגבי תקופת ניסיון חוזר ומספר הניסיונות המקסימלי.

UT עדכון חותמת הזמן. מציין את היום/השעה שבהם העדכון האחרון של האפליקציה הזו הועלתה ופורסם.

השרת מחזיר את התוספת הזאת רק עבור LICENSED_OLD_KEYS תגובות, כדי לאפשר ל-Policy לקבוע כמה הזמן שחלף מאז פורסם עדכון עם מפתחות רישוי חדשים לפני כן דחיית הגישה של המשתמש לאפליקציה.

FILE_URL1 או FILE_URL2 כתובת ה-URL של קובץ הרחבה (1 היא של הקובץ הראשי, 2 הוא קובץ התיקון). שימוש בתוכן הזה כדי מורידים את הקובץ דרך HTTP.
FILE_NAME1 או FILE_NAME2 השם של קובץ ההרחבה (1 הוא הקובץ הראשי, 2 הוא קובץ התיקון). צריך להשתמש בהרשאה הזו השם בזמן שמירת הקובץ במכשיר.
FILE_SIZE1 או FILE_SIZE2 גודל הקובץ בבייטים (1 הוא הקובץ הראשי, 2 הוא קובץ התיקון). שימוש בתוכן הזה כדי לעזור בהורדה ולוודא שיש מספיק מקום פנוי במכשיר המשותף מיקום האחסון לפני ההורדה.

תוקף הרישיון

שרת הרישוי של Google Play מגדיר תקופת תוקף רישיון לכל המשתמשים אפליקציות שהורדתם. התקופה מציינת את מרווח הזמן שבו צריך להתייחס לסטטוס הרישיון של האפליקציה כסטטוס שלא ניתן לשינוי ואפשר לשמור אותו במטמון על ידי רישיון Policy בבקשה. שרת הרישוי כולל את תקופת התוקף בתגובה לכל בדיקות הרישיון, בתוספת חותמת זמן של סיום התוקף של התשובה כתוספת למפתח VT. א' Policy יכול לחלץ את הערך של מפתח VT ולהשתמש בו כדי לאפשר גישה באופן מותנה אל את הבקשה ללא בדיקה חוזרת של הרישיון, עד לתקופת התוקף בתוקף עד.

תוקף הרישיון מאותת ל-Policy של הרישוי כשצריך לבדוק שוב את סטטוס הרישוי של שרת הרישוי. התוכן הזה לא מיועד לרמוז האם האפליקציה מורשית לשימוש בפועל. כלומר, כאשר תוקף הרישיון של הבקשה יפוג, זה לא אומר כבר לא מורשה לשימוש — במקום זאת, הוא מציין רק על Policy לבדוק שוב את סטטוס הרישיון מול השרת. לכן, כל עוד תקופת תוקף הרישיון לא הסתיימה, אנו מאשרים Policy כדי לשמור את סטטוס הרישיון הראשוני במטמון באופן מקומי ולהחזיר את הרישיון ששמור במטמון במקום לשלוח בדיקת רישיון חדשה לשרת.

שרת הרישוי מנהל את תקופת התוקף כאמצעי שעוזר לאכוף את הרישיון באופן תקין במהלך תקופת ההחזר הכספי שמוצעת על ידי Google Play לאפליקציות בתשלום. היא מגדירה את תקופת התוקף לפי האם האפליקציה נרכשה ואם כן, לפני כמה זמן. ובאופן ספציפי, השרת מגדיר תקופת תוקף באופן הבא:

  • עבור אפליקציה בתשלום, השרת מגדיר את תקופת התוקף הראשונית של הרישיון כך שתגובת הרישיון תישאר בתוקף כל עוד הבקשה עם החזר כספי. רישיון Policy באפליקציה עשוי לשמור במטמון את תוצאה של בדיקת הרישיון הראשונית ואין צורך לבדוק שוב את הרישיון עד לסיום תקופת התוקף.
  • כאשר לא ניתן יותר לבצע החזר כספי על אפליקציה, השרת מגדירה תקופת תוקף ארוכה יותר – בדרך כלל מספר ימים.
  • עבור אפליקציה חינמית, השרת מגדיר את תקופת התוקף לערך גבוה מאוד ערך (long.MAX_VALUE). כך אפשר להבטיח שבתנאי שה-Policy שמר במטמון את חותמת הזמן של התוקף באופן מקומי, לא יהיה צורך לבדוק שוב את סטטוס הרישיון של האפליקציה בעתיד.

ההטמעה של ServerManagedPolicy משתמשת בחותמת הזמן שחולצה (mValidityTimestamp) בתור תנאי ראשי כדי לקבוע אם כדי לבדוק שוב את סטטוס הרישיון מול השרת לפני שמאפשרים למשתמש גישה ל את האפליקציה.

תקופה של ניסיון חוזר ומספר מקסימלי של ניסיונות חוזרים

במקרים מסוימים, תנאי המערכת או הרשת יכולים למנוע בדיקת הרישיונות לא להגיע לשרת הרישוי, או למנוע תגובה מאפליקציית הלקוח של Google Play. לדוגמה, משתמש עשוי להפעיל אפליקציה כשאין רשת סלולרית או נתונים בזמן אמת - למשל בטיסה - או כאשר החיבור לרשת לא יציב או שהאות הסלולרי חלש.

כאשר בעיות ברשת מונעות או מפריעות לבדיקת הרישיון, Google לקוח Play מודיע לאפליקציה על ידי החזרת קוד תגובה RETRY ל- באמצעות processServerResponse() של Policy. במקרה של המערכת למשל כאשר האפליקציה לא יכולה להיות מחויבת ILicensingService, הספרייה LicenseChecker עצמה קוראת ל שיטת processServerResponse() של המדיניות עם קוד תגובה RETRY.

באופן כללי, קוד התגובה RETRY הוא אות לאפליקציה אירעה שגיאה שמנעה את השלמת בדיקת הרישיון.

שרת Google Play עוזר לאפליקציה לנהל את הרישוי במסגרת תנאי שגיאה על ידי הגדרה של 'תקופת חסד' לניסיון חוזר וערך מקסימלי מומלץ היא מספר הניסיונות החוזרים. השרת כולל את הערכים האלה בכל התגובות לבדיקת רישיונות, להוסיף אותן כתוספות מתחת למפתחות GT ו-GR.

האפליקציה Policy יכולה לחלץ את התוספות GT ו-GR ולהשתמש בהן כדי תאפשר גישה לאפליקציה באופן מותנה, באופן הבא:

  • עבור בדיקת רישיון שמסתיימת בתגובה RETRY, Policy צריך לשמור את קוד התגובה RETRY במטמון ולהגדיל את מספר התגובות של RETRY.
  • Policy צריך לאפשר למשתמש לגשת לאפליקציה, כל עוד תקופת החסד של הניסיון החוזר עדיין פעילה או המספר המקסימלי של הניסיונות החוזרים עדיין לא הופיע.

השדה ServerManagedPolicy משתמש בערכים GT ו-GR שסופקו על ידי השרת, שתוארו למעלה. הדוגמה הבאה מציגה את הטיפול המותנה של הניסיון החוזר תשובות בשיטה allow(). המספר של RETRY תגובות הוא נשמר בשיטה processServerResponse(), לא מוצג.

Kotlin

fun allowAccess(): Boolean {
    val ts = System.currentTimeMillis()
    return when(lastResponse) {
        LICENSED -> {
            // Check if the LICENSED response occurred within the validity timeout.
            ts <= validityTimestamp  // Cached LICENSED response is still valid.
        }
        RETRY -> {
            ts < lastResponseTime + MILLIS_PER_MINUTE &&
                    // Only allow access if we are within the retry period
                    // or we haven't used up our max retries.
                    (ts <= retryUntil || retryCount <= maxRetries)
        }
        else -> false
    }
}

Java

public boolean allowAccess() {
    long ts = System.currentTimeMillis();
    if (lastResponse == LicenseResponse.LICENSED) {
        // Check if the LICENSED response occurred within the validity timeout.
        if (ts <= validityTimestamp) {
            // Cached LICENSED response is still valid.
            return true;
        }
    } else if (lastResponse == LicenseResponse.RETRY &&
                ts < lastResponseTime + MILLIS_PER_MINUTE) {
        // Only allow access if we are within the retry period
        // or we haven't used up our max retries.
        return (ts <= retryUntil || retryCount <= maxRetries);
    }
    return false;
}