HTTPS และ Secure Context
HTTPS และ Secure Context
หัวข้อที่มีชื่อว่า “HTTPS และ Secure Context”Service worker และ API อื่นๆ ของ PWA ทำงานเฉพาะในสิ่งที่ browser เรียกว่า secure context การทำความเข้าใจว่า secure context คืออะไร ทำไมจึงสำคัญ และจะตรวจสอบได้อย่างไร จะช่วยให้คุณหลีกเลี่ยงปัญหาที่น่าหงุดหงิดในระหว่างการพัฒนาและ deployment
Secure context คืออะไร
หัวข้อที่มีชื่อว่า “Secure context คืออะไร”Secure context คือ environment ที่ตรงตามมาตรฐานขั้นต่ำของการรับรองความถูกต้องและความลับ ตามที่กำหนดโดย W3C ในทางปฏิบัติ หน้าจะอยู่ใน secure context เมื่อ:
- ถูก serve ผ่าน HTTPS (เช่น
https://example.com) - หรือทำงานบน
localhostหรือ127.0.0.1(ข้อยกเว้นพิเศษสำหรับการพัฒนา)
หน้าที่ถูก serve ผ่าน http:// ในทุกโดเมนอื่นนอกจาก localhost ไม่ใช่ secure context ไม่ว่าจะ deploy ที่ไหน
ทำไม service worker จึงต้องการ secure context
หัวข้อที่มีชื่อว่า “ทำไม service worker จึงต้องการ secure context”Service worker เป็น proxy ที่ทรงพลัง สามารถ intercept ทุก request จากแอปของคุณ แก้ไข response และ cache เนื้อหาได้ หากถูก serve ผ่าน HTTP ทั่วไป ผู้โจมตีที่อยู่บนเครือข่ายเดียวกัน (man-in-the-middle) สามารถ:
- แทนที่ script ของ service worker ด้วยโค้ดที่เป็นอันตรายได้
- Intercept หรือดัดแปลง response ที่ service worker cache ไว้
- ดักจับข้อมูลส่วนตัวก่อนที่จะถูกส่ง
การกำหนดให้ต้อง HTTPS จะทำให้แน่ใจว่า service worker ที่ browser รัน เป็นของจริงและไม่ถูกดัดแปลง
การตรวจสอบ window.isSecureContext
หัวข้อที่มีชื่อว่า “การตรวจสอบ window.isSecureContext”Browser เปิดเผย flag boolean ที่คุณสามารถตรวจสอบได้ตลอดเวลา:
if (window.isSecureContext) { console.log('Running in a secure context — service worker APIs available.');} else { console.warn('Not a secure context. PWA features will be unavailable.');}ตรวจสอบ flag นี้ก่อนที่จะพยายาม register service worker หรือใช้ API อื่นๆ ที่ต้องการ secure context (Push, Notifications, Web Authentication, Web Crypto) เพื่อให้ message error ที่ชัดเจนแก่ผู้ใช้แทนที่จะเห็น exception ที่ไม่ได้จัดการ
Mixed content blocking
หัวข้อที่มีชื่อว่า “Mixed content blocking”แม้ว่า origin หลักของคุณจะเป็น HTTPS แต่ browser จะบล็อก mixed content — resource ที่โหลดผ่าน HTTP จากหน้า HTTPS
- Active mixed content (scripts, stylesheets, iframes) ถูกบล็อกโดยค่าเริ่มต้นในทุก browser สมัยใหม่
- Passive mixed content (images, audio, video) อาจถูกบล็อกหรือแสดง warning เช่นกัน ขึ้นอยู่กับการตั้งค่า browser
หากหน้า HTTPS ของคุณโหลด resource ผ่าน http:// การ register service worker อาจยังคงทำงานได้ แต่ resource เหล่านั้นจะถูกบล็อกหรือทำให้ lock indicator ใน address bar เสียหาย ตรวจสอบ DevTools Console และ Network tab เพื่อค้นหาคำเตือน mixed content
กฎ scope ของ service worker
หัวข้อที่มีชื่อว่า “กฎ scope ของ service worker”Service worker ควบคุม URL ภายใน scope ของตัวเอง ซึ่งค่าเริ่มต้นคือ directory ที่ script ของ SW อยู่ Scope นี้ถูกจำกัดโดย HTTPS อีกชั้น:
- SW ที่ serve จาก
https://example.com/app/sw.jsควบคุมเฉพาะ URL ภายใต้/app/ - SW ไม่สามารถยกระดับ scope ของตัวเองให้สูงกว่า path ของไฟล์ SW ได้ ยกเว้นจะมี
Service-Worker-Allowedresponse header - ใน HTTPS ทั้งหมดนี้ถูก enforce อย่างเคร่งครัด — ไม่มี loophole ใดที่จะอนุญาตให้ SW ที่ไม่น่าเชื่อถือ intercept traffic ที่ไม่ได้ตั้งใจให้ SW ตัวนั้นเข้าถึง
ข้อยกเว้น localhost
หัวข้อที่มีชื่อว่า “ข้อยกเว้น localhost”localhost และ 127.0.0.1 ได้รับการยกเว้นโดยทั้ง spec และ browser ว่าเป็น secure context แม้ว่าจะ serve ผ่าน http:// ก็ตาม เหตุผลคือ traffic บน localhost ไม่เคยผ่านเครือข่าย ดังนั้นความเสี่ยงจาก man-in-the-middle จึงไม่มี
ในทางปฏิบัติ:
- server dev ท้องถิ่นของคุณบน
http://localhost:5173เป็น secure context ที่สมบูรณ์ - Service worker, Push API และ Web Authentication ทั้งหมดทำงานได้บน localhost โดยไม่ต้องมี TLS certificate
- เมื่อ deploy เป็น production ต้องใช้ HTTPS จริง — ข้อยกเว้น localhost ไม่ครอบคลุม IP หรือ hostname อื่น
// Safe registration pattern — checks secure context firstasync function registerServiceWorker() { if (!window.isSecureContext) { console.warn('Secure context required. Skipping service worker registration.'); return; } if (!('serviceWorker' in navigator)) { console.warn('Service workers not supported in this browser.'); return; } try { const reg = await navigator.serviceWorker.register('/sw.js'); console.log('SW registered. Scope:', reg.scope); } catch (err) { console.error('SW registration failed:', err); }}
registerServiceWorker();ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| บังคับ HTTPS ทุก origin (รวม subdomain) | service worker และ API สมัยใหม่ทำงานได้เต็มรูปแบบ ปลอดภัยจาก MITM | ต้องจัดการ TLS cert และ redirect ให้ครบทุก environment รวม staging |
| อนุญาต localhost แบบ HTTP สำหรับ dev | พัฒนาและทดสอบได้เร็วโดยไม่ต้องตั้ง cert local | ต้องระวังไม่ให้ config นี้หลุดไปที่ production โดยไม่ตั้งใจ |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- ลืมว่า mixed content (โหลด asset ผ่าน http:// บนหน้า https://) ทำให้ browser บล็อก request นั้นเงียบๆ
- ตั้ง redirect จาก HTTP ไป HTTPS ที่ระดับ app แทนที่จะทำที่ edge/CDN ทำให้ยังมี window ที่ request แรกไม่ปลอดภัย
- ไม่ต่ออายุ TLS certificate ทันเวลา ทำให้ service worker ที่เคยลงทะเบียนไว้ใช้งานไม่ได้ทันทีที่ cert หมดอายุ
💡 ตัวอย่างจากของจริง
Google Chrome — ตั้งแต่ปี 2018 เริ่มขึ้น label “Not Secure” ให้ทุกเว็บที่ไม่ใช่ HTTPS บังคับให้ทั้งอุตสาหกรรมย้ายมาใช้ TLS
Let’s Encrypt — ให้ TLS certificate ฟรีอัตโนมัติ ทำให้ต้นทุนของการทำ HTTPS ทุก origin ลดลงจนแทบไม่มีข้อแก้ตัวที่จะไม่ทำ