הוספת כותרות נוספות לבקשת 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 ברשימת ההיתרים
מגרסה Chrome 86 ואילך ברשימת ההיתרים, לא בסטטוס 'מאושר' כאשר מוגדר קישור לנכס דיגיטלי

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

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

רקע

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

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

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

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

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

הוספת כותרות נוספות לאובייקטים מסוג Intent של כרטיסייה מותאמת אישית

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

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

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

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