คำขอ HTTP มีส่วนหัว เช่น User-Agent หรือ Content-Type นอกจากส่วนหัวที่เบราว์เซอร์แนบมา แอป Android ยังอาจเพิ่มส่วนหัวเพิ่มเติม เช่น คุกกี้หรือ Referrer ผ่าน EXTRA_HEADERS
Intent Extra Chrome จะกรองส่วนหัวเพิ่มเติมบางส่วนออกเพื่อเหตุผลด้านความปลอดภัย โดยขึ้นอยู่กับวิธีและตำแหน่งที่เปิดใช้งาน Intent
คำขอข้ามแหล่งที่มาต้องมีการรักษาความปลอดภัยอีกชั้น เนื่องจากไคลเอ็นต์และเซิร์ฟเวอร์ไม่ได้เป็นของบุคคลเดียวกัน คู่มือนี้จะกล่าวถึงการเปิดคําขอดังกล่าวผ่าน Chrome Custom Tab นั่นคือ Intent ที่เปิดจากแอปที่เปิด URL ในแท็บเบราว์เซอร์ ก่อนหน้านี้จนถึง Chrome 83 นักพัฒนาแอปสามารถเพิ่มส่วนหัวใดก็ได้เมื่อเปิดแท็บที่กำหนดเอง ตั้งแต่เวอร์ชัน 83 เป็นต้นไป Chrome ได้เริ่มกรองส่วนหัวข้ามแหล่งที่มาทั้งหมดยกเว้นส่วนหัวที่อยู่ในรายการที่อนุมัติ เนื่องจากส่วนหัวที่ไม่ได้อยู่ในรายการที่อนุมัติมีความเสี่ยงด้านความปลอดภัย ตั้งแต่ Chrome 86 เป็นต้นไป คุณสามารถแนบส่วนหัวที่ไม่ได้อยู่ในรายการที่อนุมัติกับคำขอข้ามแหล่งที่มาได้ เมื่อเซิร์ฟเวอร์และไคลเอ็นต์มีความเกี่ยวข้องกันโดยใช้ลิงก์ชิ้นงานดิจิทัล ลักษณะการทํางานนี้สรุปไว้ในตารางต่อไปนี้
เวอร์ชัน Chrome | ส่วนหัว CORS ที่อนุญาต |
---|---|
ก่อน Chrome 83 | approvelisted, non-approvelisted |
Chrome 83 ถึง Chrome 85 | approvelisted |
ตั้งแต่ Chrome เวอร์ชัน 86 ขึ้นไป | รายการที่อนุมัติแล้ว รายการที่ยังไม่ได้อนุมัติเมื่อตั้งค่าลิงก์เนื้อหาดิจิทัล |
ตารางที่ 1: การกรองส่วนหัว CORS ที่ไม่ได้อยู่ในรายการที่อนุมัติ
บทความนี้แสดงวิธีตั้งค่าการเชื่อมต่อที่ยืนยันแล้วระหว่างเซิร์ฟเวอร์กับไคลเอ็นต์ และใช้การเชื่อมต่อดังกล่าวเพื่อส่งส่วนหัว HTTP ที่อยู่ในรายการที่อนุมัติและไม่ได้อยู่ในรายการที่อนุมัติ คุณข้ามไปที่หัวข้อการเพิ่มส่วนหัวเพิ่มเติมลงใน Intent ของแท็บที่กำหนดเองเพื่อดูโค้ดได้
ข้อมูลเบื้องต้น
ส่วนหัวของคำขอ CORS ที่อยู่ในรายการที่อนุมัติและไม่อยู่ในรายการที่อนุมัติ
กลไกการแชร์ทรัพยากรข้ามโดเมน (CORS) ช่วยให้เว็บแอปพลิเคชันจากต้นทางหนึ่งขอทรัพยากรจากต้นทางอื่นได้ รายการส่วนหัว CORS-approvelisted ได้รับการดูแลรักษาในมาตรฐาน HTML ตัวอย่างส่วนหัวของรายการที่อนุมัติแสดงอยู่ในตารางถัดไป
ส่วนหัว | คำอธิบาย |
---|---|
accept-language | โฆษณาภาษาธรรมชาติที่ลูกค้าเข้าใจ |
content-language | อธิบายภาษาที่มีไว้สําหรับกลุ่มเป้าหมายปัจจุบัน |
ประเภทเนื้อหา | ระบุประเภทสื่อของทรัพยากร |
ตารางที่ 2: ตัวอย่างส่วนหัว CORS ในรายการที่อนุมัติ
ส่วนหัวในรายการที่อนุมัติถือว่าปลอดภัยเนื่องจากไม่มีข้อมูลผู้ใช้ที่มีความละเอียดอ่อนและไม่น่าจะทำให้เซิร์ฟเวอร์ดำเนินการที่อาจก่อให้เกิดความเสียหาย
ตัวอย่างส่วนหัวที่ไม่ได้รับอนุมัติแสดงอยู่ในตารางต่อไปนี้
ส่วนหัว | คำอธิบาย |
---|---|
bearer-token | ตรวจสอบสิทธิ์ไคลเอ็นต์ที่เซิร์ฟเวอร์ |
origin | ระบุแหล่งที่มาของคําขอ |
คุกกี้ | มีคุกกี้ที่เซิร์ฟเวอร์ตั้งค่าไว้ |
ตาราง 3: ตัวอย่างส่วนหัว CORS ที่ไม่ได้อยู่ในรายการที่อนุมัติ
มาตรฐาน HTML ไม่แนะนำให้แนบส่วนหัวที่ไม่ได้อยู่ในรายการที่อนุมัติมากับคำขอ CORS และเซิร์ฟเวอร์จะถือว่าคำขอข้ามโดเมนมีเฉพาะส่วนหัวที่อยู่ในรายการที่อนุมัติเท่านั้น การส่งส่วนหัวที่ไม่ได้อยู่ในรายการที่อนุมัติจากโดเมนข้ามแหล่งที่มาจะทำให้แอปของบุคคลที่สามที่เป็นอันตรายสร้างส่วนหัวที่ละเมิดคุกกี้ของผู้ใช้ซึ่ง Chrome (หรือเบราว์เซอร์อื่น) จัดเก็บไว้และแนบไปกับคำขอได้ คุกกี้อาจตรวจสอบสิทธิ์ธุรกรรมของเซิร์ฟเวอร์ที่เป็นอันตรายซึ่งไม่สามารถทำได้
การแนบส่วนหัวในรายการที่อนุมัติของ CORS กับคําขอแท็บที่กําหนดเอง
แท็บที่กำหนดเองเป็นวิธีพิเศษในการเปิดหน้าเว็บในแท็บเบราว์เซอร์ที่กำหนดเอง คุณสร้าง Intent ของแท็บที่กำหนดเองได้โดยใช้ CustomTabsIntent.Builder()
นอกจากนี้ คุณยังแนบส่วนหัวกับ Intent เหล่านี้ได้โดยใช้ 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 ของแท็บที่กำหนดเอง
ตั้งค่าลิงก์เนื้อหาดิจิทัล
หากต้องการอนุญาตให้ส่งส่วนหัวที่ไม่ได้อยู่ในรายการที่อนุมัติผ่าน Intent ของแท็บที่กำหนดเอง คุณต้องตั้งค่าลิงก์ชิ้นงานดิจิทัลระหว่างแอปพลิเคชัน Android กับเว็บแอปพลิเคชันเพื่อยืนยันว่าผู้เขียนเป็นเจ้าของทั้ง 2 แอปพลิเคชัน
ทำตามคำแนะนำอย่างเป็นทางการเพื่อตั้งค่าลิงก์เนื้อหาดิจิทัล สำหรับความสัมพันธ์ของลิงก์ ให้ใช้ "delegate_permission/common.use_as_origin"` ซึ่งระบุว่าแอปทั้ง 2 แอปเป็นของต้นทางเดียวกันเมื่อลิงก์ได้รับการยืนยันแล้ว
สร้าง Intent ของแท็บที่กำหนดเองด้วยส่วนหัวเพิ่มเติม
การสร้างIntent ของแท็บที่กำหนดเองทำได้หลายวิธี คุณสามารถใช้เครื่องมือสร้างที่มีให้ใน androidX ได้โดยเพิ่มไลบรารีลงในทรัพยากร Dependency ของบิลด์ ดังนี้
MULTI_LINE_CODE_PLACEHOLDER_1
สร้าง Intent และเพิ่มส่วนหัวเพิ่มเติม
MULTI_LINE_CODE_PLACEHOLDER_2
ตั้งค่าการเชื่อมต่อแท็บที่กำหนดเองเพื่อตรวจสอบลิงก์ชิ้นงาน
การเชื่อมต่อแท็บที่กำหนดเองจะใช้สำหรับตั้งค่า CustomTabsSession
ระหว่างแอปกับแท็บ Chrome เราต้องใช้เซสชันเพื่อยืนยันว่าแอปและเว็บแอปมาจากแหล่งที่มาเดียวกัน
การยืนยันจะสำเร็จก็ต่อเมื่อลิงก์เนื้อหาดิจิทัลได้รับการตั้งค่าอย่างถูกต้องเท่านั้น
เราขอแนะนำให้โทรหา CustomTabsClient.warmup()
ซึ่งช่วยให้แอปพลิเคชันเบราว์เซอร์สามารถเริ่มต้นล่วงหน้าในเบื้องหลังและเร่งกระบวนการเปิด URL ได้
MULTI_LINE_CODE_PLACEHOLDER_3
ตั้งค่าการเรียกกลับที่เปิด 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);
โค้ดแอปพลิเคชันเดโม
ดูรายละเอียดเพิ่มเติมเกี่ยวกับบริการแท็บที่กำหนดเองได้ที่นี่ ดูตัวอย่างแอปที่ใช้งานได้ได้ที่ที่เก็บ GitHub ของ android-browser-helper
สรุป
คู่มือนี้แสดงวิธีเพิ่มส่วนหัวที่กำหนดเองไปยังคำขอ CORS ของแท็บที่กำหนดเอง คุณสามารถแนบส่วนหัวในรายการอนุมัติกับคำขอ CORS ของแท็บที่กำหนดเองทุกรายการได้ โดยปกติแล้ว ระบบจะถือว่าส่วนหัวที่ไม่ได้อยู่ในรายการที่อนุมัตินั้นไม่ปลอดภัยในคําขอ CORS และ Chrome จะกรองส่วนหัวดังกล่าวโดยค่าเริ่มต้น การแนบไฟล์ดังกล่าวจะอนุญาตเฉพาะสำหรับไคลเอ็นต์และเซิร์ฟเวอร์ที่มีต้นทางเดียวกัน ซึ่งยืนยันโดยลิงก์ชิ้นงานดิจิทัล