Chrome, Firefox, Edge และอีกมากมายจะเปลี่ยนลักษณะการทำงานเริ่มต้นให้สอดคล้องกับข้อเสนอของ IETF ซึ่งก็คือ คุกกี้ที่ดีขึ้นเรื่อยๆ เพื่อให้
- คุกกี้ที่ไม่มีแอตทริบิวต์
SameSite
จะถือว่าเป็นSameSite=Lax
ซึ่งหมายความว่าลักษณะการทำงานเริ่มต้นจะจำกัดไว้เฉพาะบริบทของบุคคลที่หนึ่งเท่านั้น - คุกกี้สำหรับการใช้งานข้ามเว็บไซต์ต้องระบุ
SameSite=None; Secure
เพื่อเปิดใช้การรวมในบริบทของบุคคลที่สาม
ฟีเจอร์นี้เป็นลักษณะการทำงานเริ่มต้นตั้งแต่ Chrome 84 เวอร์ชันเสถียรเป็นต้นไป คุณควรอัปเดตแอตทริบิวต์สำหรับคุกกี้ของบุคคลที่สามหากยังไม่ได้อัปเดต เพื่อจะได้ไม่ถูกบล็อกในอนาคต
การสนับสนุนในเบราว์เซอร์ต่างๆ
ดูส่วนความเข้ากันได้ของเบราว์เซอร์ในหน้า Set-Cookie
ของ MDN
กรณีการใช้งานสำหรับคุกกี้ข้ามเว็บไซต์หรือคุกกี้ของบุคคลที่สาม
มี Use Case และรูปแบบที่พบบ่อยจำนวนมากที่ต้องส่งคุกกี้ในบริบทของบุคคลที่สาม หากคุณระบุหรือขึ้นอยู่กับกรณีการใช้งานอย่างใดอย่างหนึ่งเหล่านี้ โปรดตรวจสอบว่าคุณหรือผู้ให้บริการอัปเดตคุกกี้ของตนเพื่อให้แน่ใจว่าบริการจะทำงานได้อย่างถูกต้องต่อไป
เนื้อหาภายใน <iframe>
เนื้อหาจากเว็บไซต์อื่นที่แสดงใน <iframe>
อยู่ในบริบทของบุคคลที่สาม กรณีการใช้งานมาตรฐานมีดังนี้
- เนื้อหาที่ฝังซึ่งแชร์จากเว็บไซต์อื่นๆ เช่น วิดีโอ แผนที่ ตัวอย่างโค้ด และโพสต์บนโซเชียลเน็ตเวิร์ก
- วิดเจ็ตจากบริการภายนอก เช่น ฟังก์ชันการชำระเงิน ปฏิทิน การจอง และการจอง
- วิดเจ็ต เช่น ปุ่มโซเชียลหรือบริการป้องกันการประพฤติมิชอบที่ไม่ชัดเจนนัก
<iframes>
โดยอาจใช้คุกกี้เพื่อรักษาสถานะเซสชัน จัดเก็บค่ากำหนดทั่วไป เปิดใช้สถิติ หรือปรับเปลี่ยนเนื้อหาให้เหมาะกับผู้ใช้ที่มีบัญชีอยู่แล้ว
นอกจากนี้ เนื่องจากเว็บเขียนได้เป็นปกติ จึงใช้ <iframes>
เพื่อฝังเนื้อหาที่ดูในบริบทระดับบนสุดหรือบริบทของบุคคลที่หนึ่งด้วย คุกกี้ที่เว็บไซต์นั้นใช้จะถือว่าเป็นคุกกี้ของบุคคลที่สามเมื่อเว็บไซต์แสดงในเฟรม หากคุณตั้งใจสร้างเว็บไซต์ที่ผู้อื่นตั้งใจให้ฝังได้ง่าย ในขณะเดียวกันก็ต้องใช้คุกกี้ในการทำงานด้วย คุณต้องตรวจสอบด้วยว่าเว็บไซต์เหล่านั้นมีการทำเครื่องหมายไว้สำหรับการใช้งานข้ามเว็บไซต์ หรือคุณจะเลือกให้ไม่มีทางเลือกอื่นก็ได้
คำขอ "ไม่ปลอดภัย" ในเว็บไซต์ต่างๆ
แม้ว่าคำว่า "ไม่ปลอดภัย" อาจฟังดูน่ากังวลเล็กน้อยในที่นี้ แต่เป็นคำขอใดก็ตามที่อาจมีเจตนาให้เปลี่ยนสถานะ บนเว็บที่เป็นคำขอ POST เป็นหลัก
คุกกี้ที่มีเครื่องหมาย SameSite=Lax
จะส่งไปในการนำทางระดับบนสุดที่ปลอดภัย เช่น การคลิกลิงก์เพื่อไปยังเว็บไซต์อื่น อย่างไรก็ตาม ตัวอย่างเช่น การส่ง <form>
ผ่าน POST ไปยังเว็บไซต์อื่นจะไม่มีคุกกี้
รูปแบบนี้ใช้สำหรับเว็บไซต์ที่อาจเปลี่ยนเส้นทางผู้ใช้ออกไปยังบริการระยะไกลเพื่อดำเนินการก่อนส่งคืน เช่น การเปลี่ยนเส้นทางไปยังผู้ให้บริการข้อมูลประจำตัวบุคคลที่สาม ก่อนที่ผู้ใช้จะออกจากเว็บไซต์ ระบบจะตั้งค่าคุกกี้ที่มีโทเค็นแบบใช้ครั้งเดียวโดยมีความคาดหวังว่าสามารถตรวจสอบโทเค็นนี้ได้ในคำขอที่ส่งคืนเพื่อลดการโจมตีด้วยการปลอมแปลงคำขอข้ามเว็บไซต์ (CSRF) หากคำขอส่งคืนดังกล่าวมาทาง POST ก็จะต้องทำเครื่องหมายคุกกี้เป็น SameSite=None; Secure
ทรัพยากรระยะไกล
ทรัพยากรระยะไกลในหน้าเว็บอาจต้องอาศัยคุกกี้ที่จะส่งไปพร้อมกับคำขอ จากแท็ก <img>
, แท็ก <script>
และอื่นๆ กรณีการใช้งานทั่วไป ได้แก่
การติดตามพิกเซลและการปรับเปลี่ยนเนื้อหาในแบบของคุณ
ซึ่งรวมถึงคำขอที่เริ่มต้นจาก JavaScript โดย fetch
หรือ XMLHttpRequest
ด้วย หากมีการเรียกใช้ fetch()
ด้วยตัวเลือก credentials: 'include'
จะเป็นตัวบ่งชี้ที่ดีว่าอาจมีการเรียกใช้คุกกี้ในคำขอเหล่านั้น
สำหรับ XMLHttpRequest
คุณควรมองหาอินสแตนซ์ของพร็อพเพอร์ตี้ withCredentials
ที่ตั้งค่าไว้เป็น true
ข้อมูลนี้เป็นตัวบ่งชี้ที่ดีว่าคำขอเหล่านั้นอาจมีคุกกี้อยู่เป็นอย่างดี คุกกี้เหล่านั้นต้องมีการทำเครื่องหมายอย่างเหมาะสมเพื่อให้รวมอยู่ในคำขอแบบข้ามเว็บไซต์
เนื้อหาภายใน WebView
WebView ในแอปเฉพาะแพลตฟอร์มขับเคลื่อนโดยเบราว์เซอร์และคุณจะต้องทดสอบว่าเป็นไปตามข้อจำกัดหรือปัญหาเดียวกันหรือไม่ ใน Android หาก WebView ขับเคลื่อนโดย Chrome ค่าเริ่มต้นใหม่จะไม่ใช้กับ Chrome 84 โดยทันที
อย่างไรก็ตาม จุดประสงค์ในการใช้โซลูชันเหล่านี้ในอนาคต คุณจึงควรทดสอบและเตรียมพร้อมสำหรับกรณีนี้ นอกจากนี้ Android ยังอนุญาตให้แอปเฉพาะแพลตฟอร์มตั้งค่าคุกกี้ผ่าน CookieManager API โดยตรงอีกด้วย
เช่นเดียวกับคุกกี้ที่ตั้งค่าผ่านส่วนหัวหรือ JavaScript ให้พิจารณาใส่ SameSite=None; Secure
หากมีไว้เพื่อการใช้งานแบบข้ามเว็บไซต์
วิธีติดตั้งใช้งาน SameSite
วันนี้เลย
สำหรับคุกกี้ที่จำเป็นเฉพาะในบริบทของบุคคลที่หนึ่งเท่านั้น คุณควรทำเครื่องหมายเป็น SameSite=Lax
หรือ SameSite=Strict
ตามความจำเป็น คุณยังสามารถเลือกไม่ทำอะไรเลยและอนุญาตให้เบราว์เซอร์บังคับใช้ค่าเริ่มต้นนั้น แต่ยังรวมถึงความเสี่ยงที่จะเกิดลักษณะการทำงานที่ไม่สอดคล้องกันในเบราว์เซอร์ต่างๆ และคำเตือนที่อาจเกิดขึ้นจากคอนโซลสำหรับคุกกี้แต่ละรายการ
Set-Cookie: first_party_var=value; SameSite=Lax
สำหรับคุกกี้ที่จำเป็นในบริบทของบุคคลที่สาม คุณจะต้องตรวจสอบว่าได้ทำเครื่องหมายเป็น SameSite=None; Secure
โปรดทราบว่าคุณต้องใช้ทั้ง 2 แอตทริบิวต์ร่วมกัน
หากคุณเพียงระบุ None
โดยไม่มี Secure
คุกกี้จะถูกปฏิเสธ การใช้งานเบราว์เซอร์มีข้อแตกต่างบางอย่างที่ใช้ร่วมกันไม่ได้ คุณจึงอาจต้องใช้กลยุทธ์ในการบรรเทาปัญหาซึ่งอธิบายไว้ในการจัดการไคลเอ็นต์ที่ทำงานร่วมกันไม่ได้ด้านล่าง
Set-Cookie: third_party_var=value; SameSite=None; Secure
การจัดการไคลเอ็นต์ที่ทำงานร่วมกันไม่ได้
เนื่องจากการเปลี่ยนแปลงเพื่อรวม None
และลักษณะการทํางานเริ่มต้นการอัปเดตยังค่อนข้างใหม่ เบราว์เซอร์จึงไม่สอดคล้องกันเกี่ยวกับวิธีจัดการการเปลี่ยนแปลงเหล่านี้ คุณไปที่หน้าอัปเดตใน chromium.org เพื่อดูปัญหาที่พบในปัจจุบันได้ แต่ไม่สามารถบอกได้หากเป็นโดยละเอียด แม้ว่าวิธีนี้จะไม่ใช่วิธีที่ดีที่สุด แต่ก็มีวิธีแก้ปัญหาเฉพาะหน้าที่คุณสามารถใช้ได้ในช่วงเปลี่ยนผ่านนี้ แต่กฎทั่วไปคือให้ถือว่าไคลเอ็นต์ที่เข้ากันไม่ได้เป็นกรณีพิเศษ อย่าสร้างข้อยกเว้นสำหรับเบราว์เซอร์
ที่ใช้กฎที่ใหม่กว่า
ตัวเลือกแรกคือการตั้งค่าทั้งคุกกี้แบบใหม่และแบบเดิม
Set-cookie: 3pcookie=value; SameSite=None; Secure
Set-cookie: 3pcookie-legacy=value; Secure
เบราว์เซอร์ที่ใช้ลักษณะการทำงานที่ใหม่กว่าจะตั้งค่าคุกกี้ด้วยค่า SameSite
ในขณะที่เบราว์เซอร์อื่นๆ อาจไม่สนใจหรือตั้งค่าไม่ถูกต้อง แต่เบราว์เซอร์เดียวกันดังกล่าวจะตั้งค่าคุกกี้ 3pcookie-legacy
ด้วย เมื่อทำการประมวลผลคุกกี้ที่มี เว็บไซต์ควรตรวจหาคุกกี้รูปแบบใหม่ที่มีอยู่ก่อน หากไม่พบคุกกี้ ให้กลับไปใช้คุกกี้เดิม
ตัวอย่างด้านล่างแสดงวิธีทำใน Node.js โดยใช้เฟรมเวิร์กของ Express และมิดเดิลแวร์cookie-parser
const express = require('express');
const cp = require('cookie-parser');
const app = express();
app.use(cp());
app.get('/set', (req, res) => {
// Set the new style cookie
res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true });
// And set the same value in the legacy cookie
res.cookie('3pcookie-legacy', 'value', { secure: true });
res.end();
});
app.get('/', (req, res) => {
let cookieVal = null;
if (req.cookies['3pcookie']) {
// check the new style cookie first
cookieVal = req.cookies['3pcookie'];
} else if (req.cookies['3pcookie-legacy']) {
// otherwise fall back to the legacy cookie
cookieVal = req.cookies['3pcookie-legacy'];
}
res.end();
});
app.listen(process.env.PORT);
ข้อเสียก็คือ วิธีนี้ต้องมีการตั้งค่าคุกกี้ซ้ำซ้อนเพื่อให้ครอบคลุมทุกเบราว์เซอร์ และต้องทำการเปลี่ยนแปลงทั้ง ณ เวลาที่ตั้งค่าและอ่านคุกกี้ อย่างไรก็ตาม วิธีนี้ควรครอบคลุมเบราว์เซอร์ทั้งหมดไม่ว่าเบราว์เซอร์จะทำงานเป็นอย่างไร และคุกกี้ของบุคคลที่สามจะยังคงทำงานต่อไปเหมือนเดิม
นอกจากนี้ ณ จุดที่ส่งส่วนหัว Set-Cookie
คุณจะเลือกตรวจหาไคลเอ็นต์ผ่านสตริง User Agent ได้ โปรดดูรายการไคลเอ็นต์ที่ใช้ร่วมกันไม่ได้แล้วใช้ไลบรารีที่เหมาะสมสำหรับแพลตฟอร์มของคุณ เช่น ไลบรารี ua-parser-js ใน Node.js
ขอแนะนำให้หาไลบรารีเพื่อจัดการการตรวจหา User Agent เนื่องจากคุณคงไม่ต้องการเขียนนิพจน์ทั่วไปเหล่านั้นด้วยตนเอง
ข้อดีของวิธีนี้คือทำการเปลี่ยนแปลงเพียงครั้งเดียวที่จุดตั้งค่าคุกกี้ อย่างไรก็ตาม คำเตือนที่จำเป็นในที่นี้คือ การดักจับข้อมูล User Agent นั้นมีความเปราะบางตามปกติและอาจไม่สามารถตรวจจับผู้ใช้ที่ได้รับผลกระทบได้ทั้งหมด
การรองรับ SameSite=None
ในภาษา ไลบรารี และเฟรมเวิร์ก
ภาษาและไลบรารีส่วนใหญ่รองรับแอตทริบิวต์ SameSite
สำหรับคุกกี้ แต่การเพิ่ม SameSite=None
ยังค่อนข้างใหม่ ซึ่งหมายความว่าคุณอาจต้องแก้ไขการทำงานมาตรฐานบางอย่างในขณะนี้
ซึ่งอธิบายไว้ในที่เก็บตัวอย่าง SameSite
รายการใน GitHub
การขอความช่วยเหลือ
คุกกี้มีอยู่เต็มไปหมด แถมเว็บไซต์ไหนๆ ก็ไม่ได้ผ่านการตรวจสอบตำแหน่งนั้นแล้วซ้ำอีก โดยเฉพาะเวลาที่มีกรณีใช้งานแบบข้ามเว็บไซต์ผสมปนเปกันไป เมื่อคุณพบปัญหา อาจเป็นครั้งแรกที่ใครก็ตาม เคยพบเจอกับปัญหานี้ ดังนั้นโปรดติดต่อเรา
- แจ้งปัญหาเกี่ยวกับที่เก็บตัวอย่าง
SameSite
รายการใน GitHub - เขียนบล็อกคำถามใน แท็ก"samesite" ใน StackOverflow
- สำหรับปัญหาเกี่ยวกับลักษณะการทำงานของ Chromium ให้รายงานข้อบกพร่องผ่านเครื่องมือติดตามปัญหา Chromium
- ติดตามความคืบหน้าของ Chrome ในหน้า
SameSite
การอัปเดต