הוספת כותרות נוספות לבקשת HTTP

בקשות HTTP מכילות כותרות כמו User-Agent או Content-Type. מלבד כותרות שמצורפים על ידי דפדפנים, אפליקציות ל-Android עשויות להוסיף עוד כותרות, כמו 'קובץ Cookie' או 'גורם מפנה' דרך EXTRA_HEADERS תוספת כוונה. מטעמי אבטחה, Chrome מסנן חלק מהכותרות הנוספות בהתאם לאופן שבו ואיפה מופעלת הכוונה.

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

גרסת Chrome מותר להשתמש בכותרות CORS
לפני Chrome 83 ברשימת ההיתרים, לא ברשימת ההיתרים
Chrome מגרסה 83 עד Chrome 85 ברשימת האישורים
מ-Chrome 86 ואילך ברשימת ההיתרים, לא ברשימת ההיתרים כשמוגדר קישור לנכס דיגיטלי

טבלה 1: סינון של כותרות CORS שלא אושרו.

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

רקע

כותרות של בקשות CORS ברשימת ההיתרים לעומת כותרות של בקשות שלא אושרו

שיתוף משאבים בין מקורות (CORS) מאפשר לאפליקציית אינטרנט ממקור אחד לבקש או משאבים ממקור אחר. רשימת הכותרות שאושרו על ידי CORS נשמרת במסגרת תקן HTML. בטבלה הבאה מוצגות דוגמאות לכותרות ברשימת האישורים:

כותרת תיאור
accept-language מפרסם שפות טבעיות שהלקוח מבין
שפת התוכן מתאר את השפה שמיועדת לקהל הנוכחי
סוג התוכן מציין את סוג המדיה של המשאב

טבלה 2: דוגמאות לכותרות CORS ברשימת אישור.

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

דוגמאות לכותרות שלא אושרו מוצגות בטבלה הבאה:

כותרת תיאור
bearer-token מאמת לקוח בשרת
מקור מציין את מקור הבקשה
קובץ Cookie מכיל קובצי cookie שהוגדרו על ידי השרת

טבלה 3: דוגמאות לכותרות CORS שלא אושרו.

לפי תקן HTML ושרתים, לא מומלץ לצרף כותרות שלא אושרו לבקשות CORS ההנחה היא שבקשות ממקורות שונים מכילות רק כותרות ברשימת האישורים. שליחת כותרות שלא אושרו מדומיינים ממקורות שונים יאפשרו לאפליקציות זדוניות של צד שלישי ליצור כותרות שמנצלות לרעה את המשתמשים קובצי Cookie ש-Chrome (או דפדפן אחר) מאחסן ומצרף לבקשות. קובצי ה-Cookie יכולים לאמת עסקאות שרת זדוניות, שלא היו אפשריות בדרך אחרת.

צירוף כותרות ברשימת ההיתרים של CORS לבקשות של כרטיסיות מותאמות אישית

כרטיסיות מותאמות אישית הן דרך מיוחדת להפעלת דפי אינטרנט בכרטיסייה מותאמת אישית בדפדפן. הכרטיסייה 'מותאם אישית' אפשר ליצור Intent באמצעות CustomTabsIntent.Builder(). אפשר גם לצרף כותרות Intents באמצעות Bundle עם הדגל Browser.EXTRA_HEADERS:

CustomTabsIntent intent = new CustomTabsIntent.Builder(session).build();

Bundle headers = new Bundle();
headers.putString("bearer-token", "Some token");
headers.putString("redirect-url", "Some redirect url");   
intent.intent.putExtra(Browser.EXTRA_HEADERS, headers);

intent.launchUrl(Activity.this, Uri.parse("http://www.google.com"));

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

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

הוספת כותרות נוספות לחיפושים של כרטיסיות מותאמות אישית

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

כדי להגדיר קישור לנכס דיגיטלי, צריך לפעול לפי המדריך הרשמי. לצורך שימוש בקשר לקישור 'lege_permission/common.use_as_origin'' מציינת ששתי האפליקציות שייכות לאותה אפליקציה מקור אחרי שהקישור מאומת.

יצירה של כוונת כרטיסייה בהתאמה אישית עם כותרות נוספות

יש כמה דרכים ליצור Intent של כרטיסיות מותאמות אישית. אפשר להשתמש בכלי ה-builder הזמין ב-androidX על ידי הוספת הספרייה ליחסי התלות של ה-build:

MULTI_LINE_CODE_PLACEHOLDER_1

לפתח את הכוונה ולהוסיף עוד כותרות:

MULTI_LINE_CODE_PLACEHOLDER_2

חיבור של 'כרטיסיות מותאמות אישית' משמש להגדרת CustomTabsSession בין האפליקציה כרטיסיית Chrome. אנחנו צריכים את הסשן כדי לאמת שהאפליקציה ואפליקציית האינטרנט שייכות לאותו מקור. האימות עובר רק אם הקישורים לנכסים דיגיטליים הוגדרו בצורה תקינה.

מומלץ להתקשר למספר CustomTabsClient.warmup(). הוא מאפשר לאפליקציית הדפדפן לאתחל מראש ברקע ולזרז את תהליך פתיחת כתובת ה-URL.

MULTI_LINE_CODE_PLACEHOLDER_3

הגדרת קריאה חוזרת (callback) שמפעילה את ה-Intent אחרי האימות

הקובץ CustomTabsCallback הועבר לסשן. אנחנו מגדירים את onRelationshipValidationResult() כדי להפעיל את CustomTabsIntent שנוצר קודם לכן כשאימות המקור מצליח.

MULTI_LINE_CODE_PLACEHOLDER_4

קישור של חיבור השירות של הכרטיסיות המותאמות אישית

קישור השירות מפעיל את השירות ואת ה-onCustomTabsServiceConnected() של החיבור תתבצע קריאה בסופו של דבר. חשוב לזכור לבטל את קישור השירות בהתאם. קישור וביטול קישור מתבצעת בדרך כלל בשיטות של מחזור החיים onStart() ו-onStop().

// Bind the custom tabs service connection.
// Call this in onStart()
CustomTabsClient.bindCustomTabsService(this,
    CustomTabsClient.getPackageName(MainActivity.this, null), connection);

// …
// Unbind the custom tabs service.
// Call this in onStop().
unbindService(connection);

קוד של אפליקציית הדגמה

ניתן למצוא פרטים נוספים על השירות של כרטיסיות מותאמות אישית כאן. לצפייה android-browser-helper מאגר GitHub בשביל אפליקציה תקינה לדוגמה.

סיכום

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