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

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

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

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

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

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

רקע

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

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

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

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

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

דוגמאות לכותרות שלא נכללות ברשימת הכותרות שאושרו מפורטות בטבלה הבאה:

כותרת תיאור
אסימון למוכ"ז אימות לקוח בשרת
מקור מציין את מקור הבקשה
קובץ cookie מכיל קובצי cookie שהוגדרו על ידי השרת

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

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

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

כרטיסיות בהתאמה אישית הן דרך מיוחדת להפעלת דפי אינטרנט בכרטיסייה מותאמת אישית בדפדפן. אפשר ליצור כוונות טירגוט בהתאמה אישית של כרטיסיות באמצעות CustomTabsIntent.Builder(). אתם יכולים גם לצרף כותרות לאובייקטים האלה באמצעות 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 מסנן כותרות שלא אושרו. יכול להיות שבדפדפנים אחרים ההתנהגות תהיה שונה, אבל מפתחים צריכים לצפות לכך שכותרות שלא נמצאות ברשימת ההיתרים ייחסמו באופן כללי.

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

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

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

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

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

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

MULTI_LINE_CODE_PLACEHOLDER_1

יוצרים את הכוונה ומוסיפים כותרות נוספות:

MULTI_LINE_CODE_PLACEHOLDER_2

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

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

MULTI_LINE_CODE_PLACEHOLDER_3

הגדרת קריאה חוזרת שמפעילה את הכוונה אחרי האימות

הקובץ 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 מסנן אותן כברירת מחדל. רק לקוחות ושרתים מאותו מקור, שמאומתים באמצעות קישור לנכס דיגיטלי, יכולים לצרף אותם.