1. ก่อนเริ่มต้น

สิ่งที่คุณจะสร้าง
ใน Codelab นี้ คุณจะได้ใช้ App Check เพื่อเพิ่มการป้องกันอีกชั้นให้กับคีย์ API ที่ใช้ในสภาพแวดล้อมเว็บ
โดยเฉพาะอย่างยิ่ง เราจะทำตามขั้นตอนต่อไปนี้ผ่าน Codelab เพื่อเชื่อมโยงฟังก์ชันการทำงานเข้าด้วยกัน
- สร้างหน้าเว็บเพื่อโฮสต์แผนที่โดยใช้ Google Maps Platform Javascript API
- โฮสต์หน้าเว็บเพื่อให้เข้าถึงได้ทางออนไลน์
- จำกัดโดเมนและ API ที่ใช้ API ได้โดยใช้ Cloud Console
- เพิ่มและเริ่มต้นใช้งานไลบรารี App Check ผ่าน Firebase
- เพิ่มผู้ให้บริการการรับรองเพื่อตรวจสอบความถูกต้องของแอปพลิเคชัน
- บังคับใช้การตรวจสอบในแอปและตรวจสอบ
เมื่อสิ้นสุด Codelab คุณควรมีเว็บไซต์ที่ใช้งานได้ซึ่งบังคับใช้ความปลอดภัยทั้งในคีย์ API ที่ใช้ โดเมนที่เข้าถึงคีย์เหล่านี้ และประเภทของแอปพลิเคชันที่ใช้คีย์ได้
2. ข้อกำหนดเบื้องต้น
การเปิดใช้ App Check ต้องใช้บริการ 3 อย่างของ Google เพื่อให้การปกป้อง คุณควรทำความคุ้นเคยกับส่วนต่างๆ เหล่านี้
Firebase - บริการนี้จะบังคับใช้บริการที่ตรวจสอบว่ามีการอ้างอิงคีย์ API จากโดเมนที่เหมาะสม ซึ่งจะช่วยให้มีฟังก์ชันการโฮสต์และการทำให้ใช้งานได้ผ่านการใช้ Firebase Studio ด้วย
reCAPTCHA - มีฟังก์ชันในการตรวจสอบว่ามนุษย์ใช้แอปพลิเคชันหรือไม่ รวมถึงมีคีย์สาธารณะและคีย์ส่วนตัวสําหรับเชื่อมต่อ Firebase กับโดเมนแอปพลิเคชันไคลเอ็นต์
Google Cloud Platform - บริการนี้มีคีย์ API ที่ทั้ง Google Maps Platform และ Firebase ใช้ รวมถึงการจำกัดโดเมนที่ใช้คีย์ Maps
คุณดูวิธีการทำงานร่วมกันขององค์ประกอบเหล่านี้ได้ในแผนภาพสถาปัตยกรรมต่อไปนี้

เมื่อใช้ App Check และ Google Maps Platform องค์ประกอบต่อไปนี้จะทำงานร่วมกันเพื่อพิจารณาว่าคำขอมาจากแอปพลิเคชันและผู้ใช้ที่ถูกต้องหรือไม่ โดยใช้การรับรองที่ผู้ให้บริการรับรองเป็นผู้ให้ ซึ่งในกรณีนี้คือ reCAPTCHA
การดำเนินการนี้จะทำผ่านการใช้ App Check SDK ที่ Firebase จัดเตรียมไว้ ซึ่งจะตรวจสอบความถูกต้องของแอปพลิเคชันที่เรียกใช้ จากนั้นจะให้โทเค็นแก่แอปพลิเคชันซึ่งใช้ในการเรียก Google Maps Platform JavaScript API ในครั้งต่อๆ ไป ในทางกลับกัน Google Maps Platform Javascript API จะตรวจสอบความถูกต้องของโทเค็นที่ระบุด้วย Firebase เพื่อให้แน่ใจว่าโทเค็นมาจากทั้งโดเมนที่ถูกต้องและผ่านผู้ให้บริการการรับรองจากผู้ใช้ที่ถูกต้อง
ดูรายละเอียดเพิ่มเติมเกี่ยวกับการใช้ App Check และ Maps JavaScript API ได้ที่ตำแหน่งต่อไปนี้ และคุณควรทำความคุ้นเคยกับขั้นตอนที่จำเป็น
https://developers.google.com/maps/documentation/javascript/maps-app-check
3. ตั้งค่า
หากยังไม่มีบัญชี Google Cloud คุณจะต้องสร้างบัญชีโดยเปิดใช้การเรียกเก็บเงินตั้งแต่เริ่มต้น ทำตามวิธีการเพื่อสร้างสิ่งนี้ก่อนเริ่ม
ตั้งค่า Google Maps Platform
หากยังไม่มีบัญชี Google Cloud Platform และโปรเจ็กต์ที่เปิดใช้การเรียกเก็บเงิน โปรดดูคู่มือการเริ่มต้นใช้งาน Google Maps Platform เพื่อสร้างบัญชีสำหรับการเรียกเก็บเงินและโปรเจ็กต์
- ใน Cloud Console ให้คลิกเมนูแบบเลื่อนลงของโปรเจ็กต์ แล้วเลือกโปรเจ็กต์ที่ต้องการใช้สำหรับ Codelab นี้

- เปิดใช้ Google Maps Platform APIs และ SDK ที่จำเป็นสำหรับ Codelab นี้ใน Google Cloud Marketplace โดยทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้
- สร้างคีย์ API ในหน้าข้อมูลเข้าสู่ระบบของ Cloud Console คุณสามารถทำตามขั้นตอนในวิดีโอนี้หรือเอกสารประกอบนี้ คำขอทั้งหมดที่ส่งไปยัง Google Maps Platform ต้องมีคีย์ API
ข้อกำหนดอื่นๆ สำหรับ Codelab นี้
หากต้องการทำ Codelab นี้ให้เสร็จสมบูรณ์ คุณจะต้องมีบัญชี บริการ และเครื่องมือต่อไปนี้
- ความรู้พื้นฐานเกี่ยวกับ JavaScript, HTML และ CSS
- บัญชี Google Cloud ที่เปิดใช้การเรียกเก็บเงินแล้ว (ตามที่ระบุไว้)
- คีย์ API ของ Google Maps Platform ที่เปิดใช้ Maps JavaScript API (ขั้นตอนนี้จะดำเนินการในระหว่างการทำโค้ดแล็บ)
- ความเข้าใจพื้นฐานเกี่ยวกับเว็บโฮสติ้งและการติดตั้งใช้งาน (คุณจะได้รับคำแนะนำใน Codelab) โดยจะดำเนินการผ่านคอนโซล Firebase และ Firebase Studio
- เว็บเบราว์เซอร์เพื่อดูไฟล์ขณะทำงาน
4. สร้างหน้าใน Firebase Studio
Codelab นี้ไม่ได้ถือว่าคุณสร้างแอปพลิเคชันไว้แล้ว และใช้ Firebase Studio เพื่อสร้างหน้าเว็บสำหรับโฮสต์แอปพลิเคชันแผนที่และนำไปใช้งานใน Firebase เพื่อวัตถุประสงค์ในการทดสอบ หากมีแอปพลิเคชันอยู่แล้ว คุณก็ใช้แอปพลิเคชันนั้นแทนได้เช่นกัน โดยเปลี่ยนโดเมนโฮสต์ที่เหมาะสม ข้อมูลโค้ด และคีย์ API เพื่อให้มั่นใจว่ามีการติดตั้งใช้งานอย่างถูกต้อง
ไปที่ Firebase Studio (ต้องใช้บัญชี Google) แล้วสร้างแอปพลิเคชัน HTML อย่างง่ายใหม่ คุณอาจต้องคลิกปุ่ม "ดูเทมเพลตทั้งหมด" เพื่อแสดงตัวเลือกนี้ หรือเพียงคลิกลิงก์นี้เพื่อเข้าถึงโดยตรง

ตั้งชื่อพื้นที่ทำงานให้เหมาะสม เช่น myappcheck-map (บวกหมายเลขสุ่มเพื่อให้ไม่ซ้ำกัน ระบบจะเพิ่มให้คุณ) จากนั้น Firebase Studio จะสร้างพื้นที่ทำงาน

เมื่อกรอกชื่อแล้ว ให้คลิกปุ่มสร้างเพื่อเริ่มกระบวนการสร้างโปรเจ็กต์

เมื่อสร้างแล้ว คุณสามารถแทนที่ข้อความในไฟล์ index.html ด้วยโค้ดต่อไปนี้ ซึ่งจะสร้างหน้าเว็บที่มีแผนที่
<!doctype html>
<html>
<head>
<title>Secure Map</title>
<style>
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;
}
</style>
</head>
<body>
<h3>App Check Security Demo</h3>
<!--The div element for the map -->
<div id="map"></div>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "YOUR_API_KEY",
v: "weekly",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map;
async function initMap() {
const { Map } = await google.maps.importLibrary("maps");
map = new Map(document.getElementById("map"), {
center: { lat: 51.5208, lng: -0.0977 },
zoom: 17,
});
}
initMap();
</script>
</body>
</html>
เมื่อเรียกใช้แล้ว ควรแสดงหน้าเว็บที่แสดงแผนที่ของแอปพลิเคชันที่ใช้งานได้ตามที่แสดงในรูปภาพ แต่!

เมื่อโหลดหน้าเว็บจริง ระบบจะแสดงข้อผิดพลาดเนื่องจากต้องใช้คีย์ API ของ Google Maps Platform ในหน้าเว็บ ซึ่งจะเพิ่มในส่วนถัดไป

คุณอาจเห็นข้อความแสดงข้อผิดพลาดจริงในคอนโซลเว็บใน Firebase Studio

เราจะต้องเพิ่มคีย์ API ลงในหน้าเว็บเพื่อแก้ไขปัญหานี้ คีย์ API เป็นวิธีที่หน้าเว็บและการติดตั้งใช้งาน Maps JavaScript API เชื่อมโยงกัน นอกจากนี้ยังเป็นช่องโหว่ด้วย เนื่องจากต้องอยู่ในหน้าเว็บในลักษณะที่ไม่ได้เข้ารหัส ซึ่งอาจมีการนำคีย์ API ไปใช้ในเว็บไซต์อื่น
วิธีการป้องกันอย่างหนึ่งคือการใช้การจำกัดแอปพลิเคชัน ไม่ว่าจะผ่านประเภทของแอปพลิเคชันที่ใช้ หรือผ่านโดเมนหรือที่อยู่ IP ที่อ้างอิงที่เรียกใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับแนวทางปฏิบัติแนะนำได้ที่เว็บไซต์ต่อไปนี้
https://developers.google.com/maps/api-security-best-practices#rec-best-practices
หรือผ่านการใช้การเรียกโดยตรงจากบรรทัดคำสั่งหรือเซิร์ฟเวอร์ แอปพลิเคชันที่ไม่มีวิธีระบุผู้เข้าชมที่มาหรือติดตามด้วยตัวเอง จึงอาจเป็นช่องโหว่ด้านความปลอดภัย
5. สร้างแอปพลิเคชัน Firebase
Firebase ใช้เพื่อมอบฟังก์ชันการทำงานในการเชื่อมโยงผู้ให้บริการการรับรองเพื่อตรวจสอบสิ่งต่อไปนี้
- คำขอมาจากแอปที่ถูกต้องของคุณ
- คำขอมาจากอุปกรณ์และเซสชันของผู้ใช้ที่เชื่อถือได้และไม่มีการดัดแปลง
ใน Codelab นี้ เราจะใช้ reCAPTCHA v3 เป็นผู้ให้บริการการรับรองนี้
สร้างแอปพลิเคชัน Firebase และโฮสต์
ไปที่ https://firebase.google.com/ แล้วสร้างโปรเจ็กต์ Firebase ใหม่จากลิงก์ "ไปที่คอนโซล"

สร้างโปรเจ็กต์ใหม่โดยคลิกที่พื้นที่ต่อไปนี้

เลือกชื่อโปรเจ็กต์ เช่น My App Check Project ชื่อนี้ไม่จำเป็นต้องเหมือนกับชื่อที่ใช้ก่อนหน้านี้ เนื่องจากเป็นเพียงข้อมูลอ้างอิง คุณสามารถแก้ไขชื่อจริงของโปรเจ็กต์ได้ที่ด้านล่างข้อความ โดยชื่อจะประกอบด้วยชื่อที่คุณป้อน และหากชื่อไม่ซ้ำกัน ระบบจะเพิ่มหมายเลขต่อท้าย

หากระบบแจ้งให้เพิ่มบริการอื่นๆ (เช่น Google Analytics) ลงในแอปพลิเคชัน คุณจะยอมรับหรือไม่ก็ได้ แต่สำหรับ Codelab นี้ไม่จำเป็น จึงอาจปล่อยไว้ได้
คลิกปุ่ม "สร้างโปรเจ็กต์" แล้วรอให้ระบบสร้างโปรเจ็กต์ ระบบจะแจ้งให้คุณทราบเมื่อดำเนินการเสร็จสิ้น

คลิก "ต่อไป" เมื่อพร้อมเริ่มโต้ตอบกับโปรเจ็กต์

จากหน้าหลัก คุณสามารถเลือกเริ่มต้นใช้งานโดยเพิ่ม Firebase ลงในแอปและเลือกตัวเลือกเว็บ

เลือกตั้งค่าโฮสติ้งของ Firebase ให้กับเว็บไซต์เพื่อให้มีที่เก็บไฟล์เมื่อนำไปใช้งาน (สำหรับเว็บไซต์จริง คุณอาจใช้ตัวเลือกของคุณเอง แต่หากต้องการทำตาม Codelab นี้ คุณจะต้องนำไปใช้งานกับโฮสติ้งของ Firebase)

คลิกลงทะเบียนแอปเพื่อสร้างแอปพลิเคชัน จากนั้นคุณจะนำสคริปต์ที่สร้างขึ้นไปใช้เพื่ออ้างอิงโปรเจ็กต์ใน Firebase จากเว็บแอปพลิเคชันของเรา
โค้ดการกำหนดค่า Firebase ในแท็บถัดไปจะใช้ในแอปพลิเคชันเพื่อเชื่อมต่อ Firebase และ Maps API เข้าด้วยกัน ดังนั้นจึงควรคัดลอกจากส่วน"ใช้แท็กสคริปต์" ซึ่งคุณจะวางใน index.html ของโปรเจ็กต์

คลิกถัดไปสำหรับส่วนอื่นๆ แล้วดูแอปที่สร้างขึ้นในส่วนการตั้งค่าโปรเจ็กต์ของเว็บไซต์
หากต้องการย้อนกลับและดูรายละเอียดการกำหนดค่าในภายหลัง คุณยังดูรายละเอียดแอปได้จากปุ่ม "การตั้งค่า" ดังที่แสดง

ก่อนออกจากส่วนนี้ คุณจะต้องจดโดเมนของเว็บไซต์โฮสติ้งของ Firebase ที่สร้างขึ้นเพื่อใช้กับ reCAPTCHA ในภายหลัง ซึ่งจะช่วยให้ชื่อเว็บไซต์เชื่อมโยงกับผู้ให้บริการการรับรองได้ ซึ่งหมายความว่าเฉพาะคำขอจากเว็บไซต์นั้นเท่านั้นที่จะได้รับการยืนยัน
ไปที่ส่วนโฮสติ้งจากทางลัดของโปรเจ็กต์หรือเมนูสร้างทางด้านซ้าย
หรือ 
และจากส่วนนั้น ให้ค้นหาโดเมนที่สร้างขึ้นสำหรับแอปพลิเคชัน คุณอาจต้องคลิกผ่าน 2-3 หน้าจอเพื่อตั้งค่าหากยังไม่ได้ดำเนินการ

6. คีย์ API ที่ปลอดภัย
ไปที่ Cloud Console ในบัญชีเดียวกันกับที่ใช้ Firebase เพื่อดูโปรเจ็กต์ที่สร้างขึ้น

หากมีหลายโปรเจ็กต์ คุณอาจต้องใช้เมนูแบบเลื่อนลงหรือช่องค้นหาเพื่อเลือกโปรเจ็กต์ที่ถูกต้องพร้อมชื่อโปรเจ็กต์ Firebase

ซึ่งจะเป็นการเปิดโปรเจ็กต์ที่สร้างขึ้นใหม่ ตอนนี้คุณจะเพิ่ม Maps JavaScript API ลงในโปรเจ็กต์นี้เพื่อให้ใช้ภายในโปรเจ็กต์ได้ ซึ่งรวมถึงการจำกัดการใช้งานไว้ที่คีย์ API และโดเมนโฮสติ้งที่เฉพาะเจาะจง

ใช้เมนูด้านซ้ายเพื่อเปิดใช้ Maps API ในโปรเจ็กต์ เลือกตัวเลือก "API และบริการ" และ "API และบริการที่เปิดใช้"

เลือกตัวเลือก "เปิดใช้ API และบริการ"

ป้อน "Maps JavaScript API" ในช่องค้นหา

เลือกผลการค้นหาที่ตรงกัน

จากนั้นคลิกเปิดใช้ใน API เพื่อเพิ่มลงในโปรเจ็กต์ (อาจดำเนินการไปแล้วหากคุณเคยใช้โปรเจ็กต์นี้มาก่อน)

เมื่อเปิดใช้แล้ว คุณจะเลือกเพิ่มคีย์ API และจำกัดคีย์ได้ แต่ตอนนี้เราจะข้ามขั้นตอนนี้ไปก่อน
ใช้ตัวเลือกเมนูด้านซ้ายอีกครั้ง กลับไปที่ส่วน API และบริการ แล้วเลือกคีย์เบราว์เซอร์ที่สร้างไว้ให้คุณ

เพิ่ม Maps JavaScript API ลงในการจำกัด API รายการใดรายการหนึ่ง

สำหรับคีย์ในแอปพลิเคชันที่ใช้งานจริง คุณควรจำกัดโดเมนที่โฮสต์แอปพลิเคชันด้วย โดยทำตอนนี้โดยใช้โดเมนที่สร้างให้คุณใน Firebase นอกจากนี้ คุณควรเพิ่ม /* ที่ท้ายโดเมนเพื่อให้ครอบคลุมเส้นทางทั้งหมดภายใต้โดเมนนั้น

ดูรายละเอียดเพิ่มเติมเกี่ยวกับการเปิดใช้ได้ที่ตำแหน่งต่อไปนี้เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับการจำกัดคีย์ API
https://developers.google.com/maps/api-security-best-practices#restricting-api-keys
7. สร้างข้อมูลลับ reCAPTCHA
ขั้นตอนถัดไปคือการสร้างโปรเจ็กต์ reCAPTCHA เพื่อให้การรับรองและคีย์สำหรับทั้งไคลเอ็นต์และเซิร์ฟเวอร์
ไปที่เว็บไซต์ reCAPTCHA ที่ https://www.google.com/recaptcha/ แล้วคลิกปุ่มเริ่มต้นใช้งาน

จากนั้นลงทะเบียนเว็บไซต์ใหม่ โดยตรวจสอบว่าคุณป้อนโดเมนที่ถูกต้องเพื่อจำกัด

นอกจากนี้ โปรดตรวจสอบว่าคุณได้เลือกโปรเจ็กต์ Google Cloud เดียวกันกับที่ Firebase สร้างขึ้นในกรณีที่คุณมีโปรเจ็กต์มากกว่า 1 รายการ
การดำเนินการนี้จะสร้างคีย์ 2 รายการ ได้แก่ คีย์ลับที่คุณจะป้อนลงในคอนโซล Firebase ซึ่งไม่ควรนำไปใส่ในหน้าเว็บหรือแอปพลิเคชันใดๆ ที่ดูได้แบบสาธารณะ และคีย์เว็บไซต์ที่จะใช้ในเว็บแอปพลิเคชัน

เปิดหน้านี้ไว้เนื่องจากคุณจะต้องใช้หน้านี้ คลิกปุ่มคัดลอกคีย์ลับ แล้วกลับไปที่เว็บไซต์ Firebase
8. เพิ่ม reCAPTCHA ไปยัง Firebase
ในคอนโซลผู้ดูแลระบบ Firebase ให้ไปที่รายการเมนูด้านซ้ายมือ ในรายการเมนูสร้าง ให้เลือก App Check

คุณจะเปิดใช้รายการบริการไม่ได้จนกว่าจะมีการลงทะเบียนแอป (สร้างขึ้นก่อนหน้านี้เมื่อเพิ่มการโฮสต์ลงในเว็บไซต์) คลิกเริ่มต้นใช้งานหากต้องการตั้งค่านี้
คลิกแท็บแอป แล้วเปิดเว็บแอป จากนั้นป้อนรหัสลับที่คุณคัดลอกจากเว็บไซต์ reCAPTCHA แล้วคลิกบันทึก

ตอนนี้ควรมีเครื่องหมายถูกสีเขียวข้างผู้ให้บริการ reCAPTCHA ตอนนี้เว็บแอปพลิเคชันนี้ใช้ reCAPTCHA เพื่อยืนยันได้ว่าผู้ใช้หรือเว็บไซต์เรียกใช้บริการอย่างถูกต้องหรือไม่

ในแท็บ API ตอนนี้ควรแสดงว่า Google Maps Platform API ใช้งานได้ แต่ไม่ได้บังคับใช้แล้ว

ตอนนี้คุณได้ลิงก์ข้อมูลลับของ reCAPTCHA กับโปรเจ็กต์ Firebase แล้ว และสามารถไปเพิ่มโค้ดลงในหน้าเว็บเพื่อให้ตรงกับคีย์เว็บไซต์กับผู้ให้บริการที่เหมาะสมเพื่อใช้กับแอปพลิเคชัน Maps
reCAPTCHA จะตรวจสอบคีย์เว็บไซต์เพื่อให้ตรงกับคีย์ลับ เมื่อดำเนินการเสร็จแล้ว ระบบจะยืนยันว่าหน้าเว็บที่เรียกใช้นั้นถูกต้อง และ App Check จะให้โทเค็นที่ใช้ได้ในการเรียกใช้ Maps JavaScript API ครั้งต่อๆ ไป หากไม่มีการรับรองนี้ ระบบจะไม่ให้โทเค็นและจะตรวจสอบคำขอไม่ได้
9. เพิ่มการยืนยันในหน้าเว็บและทําการติดตั้งใช้งาน
กลับไปที่ Cloud Console แล้วคัดลอกคีย์ API ที่ต้องใช้สำหรับ Maps API
คุณดูได้จากเมนูด้านข้างในคอนโซล ในเมนูด้านข้างของ API และบริการ ในตัวเลือกข้อมูลเข้าสู่ระบบ

จากที่นี่ คุณสามารถเลือกคีย์เบราว์เซอร์ที่มีอยู่ (แม้ว่าคุณจะใช้คีย์อื่นที่มีอยู่หรือสร้างคีย์ใหม่ได้ตามที่ระบุไว้)

คลิกปุ่มแสดงคีย์ แล้วคัดลอกคีย์จากกล่องโต้ตอบที่แสดง
กลับไปที่โปรเจ็กต์ Firebase Studio ที่เปิดหน้า HTML ที่คุณสร้างไว้ก่อนหน้านี้ ตอนนี้คุณสามารถเพิ่มคีย์ API ลงในหน้าเว็บเพื่อให้ Maps API ทำงานในตำแหน่งที่หน้าเว็บมี "YOUR_API_KEY"

เมื่อคุณเรียกใช้หน้าเว็บอีกครั้ง คุณจะเห็นข้อความแสดงข้อผิดพลาดที่แตกต่างออกไป

ซึ่งหมายความว่าเราไม่อนุญาตโดเมนการพัฒนาที่คุณโฮสต์หน้าเว็บ (เราเพิ่มเฉพาะโดเมนที่ใช้งานจริง) เราจะต้องเผยแพร่เว็บไซต์นี้ไปยังโดเมนที่ถูกต้องโดยใช้ Firebase Hosting ดูรายละเอียดเพิ่มเติมได้ที่
ทําให้ใช้งานได้ด้วยโฮสติ้งของ Firebase
และวิดีโอนี้
สร้าง ทดสอบ และติดตั้งใช้งานเว็บแอป Firebase ได้เร็วขึ้นใน Project IDX

ดูรายละเอียดเพิ่มเติมได้ที่ส่วนข้อผิดพลาดในการโหลดแผนที่ในเว็บไซต์ Maps JavaScript API
หากคุณได้รับ RefererNotAllowedMapError คุณสามารถแก้ไขได้โดยการติดตั้งใช้งานหน้าเว็บไปยังโดเมนที่ถูกต้อง
กลับไปที่ Firebase Studio แล้วคลิกไอคอน "Firebase Studio" (ไอคอนนี้อาจอยู่ทางซ้ายสุดหรือขวาสุด ขึ้นอยู่กับตัวเลือกที่คุณตั้งค่าไว้) เพื่อเปิดตัวเลือกโฮสติ้ง

ใน Codelab นี้ คุณจะต้อง "โฮสต์แอปด้วย Firebase" เพื่อเชื่อมต่ออินสแตนซ์ Firebase กับแอปพลิเคชัน Studio

จากนั้นคลิก "ตรวจสอบสิทธิ์ Firebase" เพื่อเริ่มกระบวนการตรวจสอบสิทธิ์ ซึ่งจะช่วยให้บัญชีของคุณสามารถทำให้การโฮสต์เป็นแบบอัตโนมัติด้วยแบ็กเอนด์จากภายในสตูดิโอ

ทำตามวิธีการในหน้าต่างคำสั่งเพื่อให้สิทธิ์การติดตั้งใช้งาน

ทำตามวิธีการบนหน้าจอ (รวมถึงการเปิดหน้าต่างใหม่) และคัดลอกรหัสการให้สิทธิ์เมื่อระบบขอ แล้ววางลงในหน้าต่างคำสั่งใน Firebase Studio

ดูรายละเอียดเพิ่มเติมเกี่ยวกับกระบวนการนี้ได้ที่ตำแหน่งต่อไปนี้
https://firebase.google.com/docs/studio/deploy-app
เมื่อดำเนินการนี้เสร็จแล้ว คุณจะคลิก "เริ่มต้นโฮสติ้งของ Firebase" เพื่อลิงก์โปรเจ็กต์กับโปรเจ็กต์ Firebase ได้
เลือก "ใช้โปรเจ็กต์ที่มีอยู่" แล้วเลือกโปรเจ็กต์ที่คุณสร้างไว้ในส่วนก่อนหน้า ยอมรับค่าเริ่มต้นที่เหลือ (ตัวอย่างของคุณอาจแตกต่างกันไปขึ้นอยู่กับชื่อที่คุณเลือกเมื่อตั้งค่าโปรเจ็กต์)

กลับไปที่มุมมอง Explorer แล้วแทนที่ไฟล์ index.html ที่สร้างขึ้นในไดเรกทอรีสาธารณะด้วยไฟล์ที่คุณมีอยู่แล้วในไดเรกทอรีราก

ตอนนี้คุณกลับไปที่แถบด้านข้างของ Firebase Studio และนำเว็บไซต์ไปใช้งานจริงได้แล้ว

ซึ่งจะแสดงขั้นตอนการติดตั้งใช้งานในคอนโซล

เปิดเว็บไซต์ที่ติดตั้งใช้งานจาก "URL การโฮสต์" ที่แสดง (ที่นี่ระบุเป็น https://my-app-check-project.web.app/ แต่จะแตกต่างกันสำหรับโปรเจ็กต์ของคุณ)
ตอนนี้แอปพลิเคชันจะแสดงแผนที่ในหน้าเว็บเนื่องจาก API ทำงานสำหรับโดเมนที่ใช้

ตอนนี้มีหน้าเว็บที่ใช้งานได้ โดยมีการจำกัดประเภทของ API ที่อาจใช้กับคีย์ API รวมถึงโดเมนที่อาจใช้คีย์ API ด้วย ขั้นตอนถัดไปคือการล็อกการเข้าถึงให้เฉพาะโดเมนนั้น โดยคุณจะต้องเพิ่มส่วนสคริปต์ Firebase ที่สร้างไว้ก่อนหน้านี้เพื่อรักษาความปลอดภัยของหน้าเว็บโดยใช้ App Check ซึ่งเราจะดำเนินการในส่วนถัดไป
10. หน้าเว็บที่ปลอดภัย
แม้ว่าหน้าปัจจุบันจะรักษาความปลอดภัยของคีย์ API ให้กับโดเมน แต่ก็ไม่ได้เพิ่มขั้นตอนการรับรองเพื่อให้แน่ใจว่าแอปพลิเคชันและบุคคลที่ถูกต้องเป็นผู้ใช้ ผู้ไม่ประสงค์ดีอาจยังคงขโมยและใช้คีย์ได้ หากต้องการหยุดการกำหนดค่า Firebase นี้ คุณต้องเพิ่มคีย์ของผู้ให้บริการและคีย์ของเว็บไซต์ลงในหน้าเว็บเพื่อให้ได้โทเค็นที่ถูกต้องสำหรับไคลเอ็นต์
นอกจากนี้ คุณยังเห็นได้ว่าระบบกำลังติดตามการใช้งาน Maps API ใน Firebase เนื่องจากไม่ได้ใช้โทเค็นที่ถูกต้อง จึงทำให้เกิดคำขอที่ไม่ได้รับการยืนยัน
คุณดูรายละเอียดการเชื่อมต่อที่จำเป็นได้จากโปรเจ็กต์ Firebase
รับรายละเอียด Firebase จากคอนโซลซึ่งมีรายละเอียดการกำหนดค่า Firebase ไปที่หน้าการตั้งค่าโปรเจ็กต์ใน Firebase และในส่วน CDN ของแอป ให้ไปที่ส่วนโค้ดสำหรับการตั้งค่า CDN (ง่ายที่สุด)
ในโปรเจ็กต์ Firebase ให้เลือกฟันเฟืองเพื่อแสดงการตั้งค่าโปรเจ็กต์

ซึ่งจะเปิดหน้าต่อไปนี้ที่มีรายละเอียดในส่วนทั่วไปภายใต้แอปของคุณ

คัดลอกโค้ดนี้ลงในหน้า Firebase Studio (public/index.html) ที่มีแผนที่และโฮสต์อยู่ ซึ่งจะมีลักษณะดังนี้ (โดยมีรายละเอียดของคุณและไม่ใช่รายละเอียดในไฟล์นี้)
<!doctype html>
<html>
<head>
<title>Secure Map</title>
<style>
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;
}
</style>
</head>
<body>
<h3>App Check Security Demo</h3>
<!--The div element for the map -->
<div id="map"></div>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "YOUR_API_KEY",
v: "weekly",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script type="module">
// Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/12.2.1/firebase-app.js";
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "appcheck-map.firebaseapp.com",
projectId: "appcheck-map",
storageBucket: "appcheck-map.firebasestorage.app",
messagingSenderId: "YOUR_SENDER_KEY",
appId: "YOUR_APP_ID"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
let map;
async function initMap() {
const { Map } = await google.maps.importLibrary("maps");
map = new Map(document.getElementById("map"), {
center: { lat: 51.5208, lng: -0.0977 },
zoom: 17,
});
}
initMap();
</script>
</body>
</html>
ตอนนี้เราได้เพิ่ม Firebase ลงในแอปพลิเคชันแล้ว การเรียกใช้ไลบรารี reCAPTCHA โดยใช้คีย์ของเว็บไซต์ที่ระบุซึ่งคุณได้รับก่อนหน้านี้จากเว็บไซต์ reCAPTCHA (จากก่อนหน้านี้)

ดูรายละเอียดเพิ่มเติมเกี่ยวกับการเพิ่มส่วนเหล่านี้ได้ที่หน้าเอกสารประกอบของ Maps ต่อไปนี้
https://developers.google.com/maps/documentation/javascript/maps-app-check
เพิ่มไลบรารี App Check ลงในหน้า จากนั้นโหลดฟังก์ชันเพื่อเริ่มต้น App Check ด้วยการกำหนดค่า Firebase และรับโทเค็นโดยใช้ ReCaptchaV3Provider
ก่อนอื่น ให้นำเข้าไลบรารี App Check โดยทำดังนี้
import {
getToken,
initializeAppCheck,
ReCaptchaV3Provider,
} from "https://www.gstatic.com/firebasejs/12.2.1/firebase-app-check.js";
จากนั้นให้เพิ่มโค้ดเพื่อเริ่มต้น App Check ด้วยการกำหนดค่า Firebase และผู้ให้บริการ reCAPTCHA โดยใช้โทเค็นเว็บไซต์
// Get App Check Token
const appCheck = initializeAppCheck(app, {
provider: new ReCaptchaV3Provider('<INSERT SITE KEY>'),
isTokenAutoRefreshEnabled: true,
});
สุดท้าย ให้แนบฟังก์ชันกับตัวควบคุมแผนที่โดยใช้ฟังก์ชันการตั้งค่าของไลบรารี Maps Core เพื่อรับโทเค็น ซึ่งจะทำให้คำขอโทเค็นเป็นไปตามที่ตัวควบคุมแผนที่กำหนด โดยขึ้นอยู่กับระยะเวลาการใช้งานของโทเค็น
const { Settings } = await google.maps.importLibrary('core');
Settings.getInstance().fetchAppCheckToken = () =>
getToken(appCheck, /* forceRefresh = */ false);
ไฟล์ทั้งหมดมีลักษณะดังนี้
<!doctype html>
<html>
<head>
<title>Secure Map</title>
<style>
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;
}
</style>
</head>
<body>
<h3>App Check Security Demo</h3>
<!--The div element for the map -->
<div id="map"></div>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "YOUR_API_KEY",
v: "weekly",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script type="module">
import { initializeApp } from "https://www.gstatic.com/firebasejs/12.2.1/firebase-app.js";
import {
getToken,
initializeAppCheck,
ReCaptchaV3Provider,
} from "https://www.gstatic.com/firebasejs/12.2.1/firebase-app-check.js";
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "appcheck-map.firebaseapp.com",
projectId: "appcheck-map",
storageBucket: "appcheck-map.firebasestorage.app",
messagingSenderId: "YOUR_SENDER_KEY",
appId: "YOUR_APP_ID"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Get App Check Token
const appCheck = initializeAppCheck(app, {
provider: new ReCaptchaV3Provider('<INSERT SITE KEY>'),
isTokenAutoRefreshEnabled: true,
});
let map;
async function initMap() {
const { Map } = await google.maps.importLibrary("maps");
const { Settings } = await google.maps.importLibrary('core');
Settings.getInstance().fetchAppCheckToken = () =>
getToken(appCheck, /* forceRefresh = */ false);
map = new Map(document.getElementById("map"), {
center: { lat: 51.5208, lng: -0.0977 },
zoom: 17,
});
}
initMap();
</script>
</body>
</html>
ทำให้ใช้งานได้ในเว็บไซต์ Firebase โดยใช้ Firebase Studio แล้วเรียกใช้หน้าเว็บ
11. บังคับใช้การตรวจสอบ
ตอนนี้เมื่อตั้งค่าหน้าเว็บแล้ว เมื่อเรียกใช้ คุณจะเห็นว่าระบบกำลังตรวจสอบ กลับไปที่คอนโซล Firebase แล้วเปิดส่วน App Check อีกครั้ง ตอนนี้ App Check ควรตรวจสอบ Maps JavaScript API แล้ว

การเปิดหน้าต่างจะแสดงว่าไคลเอ็นต์กำลังส่งคำขอและว่าการรับรองทำงานได้ (แสดงด้วยคำขอ "ยืนยันแล้ว" สีน้ำเงินเข้มในกราฟ) คำขออื่นๆ จะแสดงการเรียกใช้ในระยะการพัฒนา ก่อนที่การยืนยันจะเสร็จสมบูรณ์

ตอนนี้คุณเห็นแล้วว่าไคลเอ็นต์ทำงานได้แล้ว คุณจึงเปิดใช้การบังคับใช้ในเว็บไซต์เพื่อให้แน่ใจว่าคีย์ API จะใช้จากแอปพลิเคชันไคลเอ็นต์ที่ไม่ถูกต้องไม่ได้ คลิกปุ่มบังคับใช้เพื่อเริ่มการบังคับใช้

การคลิกปุ่มนี้จะแสดงป้ายเตือนขนาดใหญ่ที่ระบุว่าการดำเนินการนี้จะล็อกแอปพลิเคชันของคุณ ในโลกแห่งความเป็นจริง คุณจะดำเนินการนี้ก็ต่อเมื่อทราบว่าไคลเอ็นต์ทั้งหมดมีคีย์ที่ถูกต้องและใช้งานได้ มิฉะนั้นผู้ใช้อาจเข้าถึงเว็บไซต์ไม่ได้

และอาจใช้เวลาสักครู่ในการบังคับใช้ ซึ่งจะแสดงบนหน้าจอ หากคุณทดสอบการบังคับใช้ทันที ระบบอาจยังไม่มีเวลาเผยแพร่

เมื่อส่งคำขอสำหรับหน้าเว็บ คุณควรจะเห็นว่าหน้าเว็บทำงานได้เหมือนเดิม เนื่องจากไม่มีการเปลี่ยนแปลงใดๆ ในเว็บไซต์
ตอนนี้คุณควรเห็นจำนวนคำขอที่ยืนยันแล้วในคอนโซลเพิ่มขึ้นเมื่อเวลาผ่านไป ดังที่เห็นได้ที่นี่

คุณสามารถทดสอบว่าใช้งานได้โดยกลับไปที่ตัวอย่างเดิมใน Codelab แล้วสร้างหน้าใหม่โดยไม่มีฟังก์ชันการตรวจสอบแอป ตั้งชื่อหน้านี้ว่า nocheck.html หรืออะไรก็ได้ แล้ววางไว้ในโฟลเดอร์สาธารณะในตำแหน่งเดียวกับ index.html
<!doctype html>
<html>
<head>
<title>Secure Map</title>
<style>
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;
}
</style>
</head>
<body>
<h3>App Check Security Demo</h3>
<!--The div element for the map -->
<div id="map"></div>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "YOUR_API_KEY",
v: "weekly",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map;
async function initMap() {
const { Map } = await google.maps.importLibrary("maps");
map = new Map(document.getElementById("map"), {
center: { lat: 51.5208, lng: -0.0977 },
zoom: 17,
});
}
initMap();
</script>
</body>
</html>
เมื่อทำตามขั้นตอนเหล่านี้และป้อนคีย์ API ที่ถูกต้องแล้ว เมื่อขอหน้าเว็บ (ใช้ yourdomain/nocheck.html) คุณควรเห็นกล่องข้อผิดพลาดสีเทาต่อไปนี้

เมื่อตรวจสอบคอนโซล คุณควรเห็นข้อความแสดงข้อผิดพลาดดังต่อไปนี้

App Check บล็อกคำขอแผนที่ในหน้าเว็บเรียบร้อยแล้ว เนื่องจากไม่ได้โทเค็น App Check สำหรับเว็บไซต์ที่บังคับใช้อีกต่อไป
12. ยินดีด้วย
ขอแสดงความยินดี คุณเปิดใช้ App Check ในเว็บไซต์เรียบร้อยแล้ว

คุณสร้างแอปพลิเคชันที่ใช้ Firebase App Check เพื่อให้แน่ใจว่าคำขอมาจากโดเมนและผู้ใช้ที่ถูกต้องเรียบร้อยแล้ว
สิ่งที่คุณได้เรียนรู้
- วิธีใช้ Firebase Studio เพื่อโฮสต์และทําให้หน้าเว็บใช้งานได้
- วิธีใช้ Cloud Console เพื่อเปิดใช้และรักษาความปลอดภัยของ API ของแพลตฟอร์ม Google Maps
- วิธีใช้ reCAPTCHA เพื่อสร้างคีย์ที่ใช้ในการรับรองการเรียกได้
- วิธีใช้ Firebase App Check และผสานรวมเข้ากับ Maps JavaScript API
- ดูวิธีบังคับใช้และตรวจสอบการเรียกไปยังเว็บไซต์ที่ได้รับการปกป้องด้วย Firebase Studio
ขั้นตอนต่อไปคืออะไร
- ดูเอกสารประกอบสำหรับ App Check สำหรับ Google Maps JavaScript API
- ดูข้อมูลเพิ่มเติมเกี่ยวกับ App Check ใน Firebase
- ลองใช้ Codelab อีกรายการกับ App Check และ Google Maps Places API
- ดูข้อมูลเพิ่มเติมเกี่ยวกับ reCAPTCHA