

เวลาทำหน้า login เราอาจเห็น server ตอบ Set-Cookie กลับมาแล้ว แต่คำขอถัดไปกลับยังถูกมองว่ายังไม่ได้เข้าสู่ระบบ หรือบางหน้าทำงานได้ขณะที่หน้าที่เรียก API อีกที่หนึ่งใช้ session ไม่ได้ อาการแบบนี้ทำให้ดูเหมือน cookie หายแบบไม่แน่นอน
ความจริงระหว่าง server ส่ง header กับบริการได้รับ cookie ในคำขอถัดไปยังมีกติกาหลายขั้น Browser ต้องยอมเก็บก่อน แล้วค่อยพิจารณาว่าคำขอแต่ละอันอยู่ในขอบเขตที่ควรแนบ cookie นั้นหรือไม่ การเห็นชื่อใน header จึงยังไม่ยืนยันทุกขั้นต่อจากนั้น
ก่อนขยาย Domain หรือเปลี่ยน SameSite จึงควรไล่ทีละขอบเขตครับ จะได้รู้ว่าปัญหาอยู่ที่การเก็บ การแนบ หรือฝั่งบริการอ่าน session แล้วไม่ยอมรับ
เริ่มจาก response ที่ตั้ง cookie ว่ามาจาก URL ใด ใช้ HTTPS หรือไม่ และ browser แจ้งเหตุที่ปฏิเสธไว้ตรงไหน หากมี header แต่ไม่ได้ถูกเก็บ การแก้โค้ดอ่าน cookie ฝั่ง API ก็ยังไม่แตะสาเหตุของขั้นแรก
เครื่องมือพัฒนาของ browser ช่วยดูค่าประกอบกับเหตุที่ถูกจำกัดได้ แต่ข้อมูล session เป็นของลับที่ไม่ควรคัดลอกทั้งค่าไปแปะใน log หรือรายงานปัญหา เราสามารถเก็บชื่อกับ attributes และสถานะการแนบโดยปกปิดค่า เพื่ออธิบายเส้นทางได้
อย่าใช้การอ่าน document.cookie เป็นทางยืนยันเพียงอย่างเดียว เพราะ cookie ที่กำหนด HttpOnly จะไม่เปิดให้ JavaScript อ่านผ่านทางนั้น แม้ browser ยังเก็บและแนบไปกับคำขอที่เข้าเงื่อนไขได้ตามปกติ

ถ้าไม่กำหนด Domain cookie จะมีขอบเขตตาม host ที่ตั้งไว้ตามกติกา ส่วนการกำหนด Domain ที่กว้างขึ้นอาจทำให้ส่งไปยัง subdomain ที่เกี่ยวข้องได้ด้วย จึงควรเลือกจากสิ่งที่ต้องใช้ร่วมกันจริง ไม่เพิ่มขอบเขตเพียงเพื่อให้ทุกคำขอเห็น cookie โดยยังไม่ตรวจความสัมพันธ์ของระบบ
Path กำหนดเส้นทาง URL ที่เข้าเงื่อนไขการส่ง เช่น cookie ของเส้นทางหนึ่งอาจไม่ถูกแนบไปยัง API ที่อยู่อีกเส้นทาง แต่ Path ไม่ใช่กลไกอนุญาตให้อ่านข้อมูลตามสิทธิ์ของบริการ และไม่ควรถูกใช้เป็นขอบเขตความปลอดภัยแทนการตรวจฝั่ง server
Cookie ยังไม่ได้แบ่งตาม port แบบ origin ของเว็บ ดังนั้นการตรวจแค่คำว่าเป็นคนละ origin อาจยังอธิบายขอบเขตการส่งไม่ครบ ต้องดู host path และคุณสมบัติอื่นของ cookie ประกอบ ไม่ใส่หมายเลข port ลงใน Domain เพื่อหวังให้เป็นกติกาเดียวกัน
Secure กำหนดเงื่อนไขการส่งผ่านช่องทางที่ปลอดภัยตาม browser รองรับ ส่วน HttpOnly จำกัดการอ่านจาก JavaScript การตั้งทั้งสองอย่างจึงตอบคนละความเสี่ยง ไม่ใช้ชื่อของ attribute หนึ่งไปอ้างว่าป้องกันทุกทางที่ค่าอาจถูกเข้าถึงได้
HttpOnly ไม่ได้ห้าม browser ใช้ cookie กับคำขอที่ script สร้าง และ Secure ก็ไม่ได้แปลว่าค่าภายใน cookie ถูกเข้ารหัสในตัวมันเอง หากใช้ cookie เป็น session ควรพิจารณารูปแบบตัวระบุและการตรวจฝั่งบริการตามระบบที่เลือก ไม่เก็บข้อมูลลับทุกอย่างไว้ใน cookie เพราะเห็นว่ามี flag เหล่านี้แล้ว
ตอนพัฒนาด้วย HTTP หรือสลับมาที่ HTTPS ควรตรวจเงื่อนไขจริงของ browser กับสภาพแวดล้อม ไม่ใช้ข้อยกเว้นของ localhost ไปยืนยันว่าการตั้งแบบเดียวกันจะทำงานเหมือนกันบนโดเมนใช้งานจริงทุกกรณี

Origin ใช้ scheme host และ port ขณะที่บริบท site มีขอบเขตตาม scheme กับโดเมนที่เกี่ยวข้องตามกติกา browser จึงเป็นไปได้ที่หน้าเว็บกับ API อยู่คนละ origin แต่ยังเป็น same-site เช่น host ย่อยของไซต์เดียวกันภายใต้ scheme ที่ตรงกัน
SameSite ใช้ควบคุมการแนบ cookie ตามบริบทข้าม site โดยมี Strict Lax และ None ที่ให้พฤติกรรมต่างกัน การเรียก API ผ่าน fetch กับการกดลิงก์นำทางหน้าเป็นคนละบริบทด้วย จึงควรตรวจชนิดคำขอจริง ไม่สรุปว่าใช้ Lax แล้วทุกการมาจากเว็บอื่นต้องได้ผลเหมือนกัน
SameSite=None ต้องใช้ Secure ตามกติกาที่เกี่ยวข้อง แต่ไม่ได้รับรองว่า cookie จากบริบท third-party จะถูกยอมรับทุกครั้ง เพราะ browser หรือการตั้งค่าของผู้ใช้ยังอาจมีนโยบายจำกัดเพิ่มเติม การเปลี่ยนเป็น None จึงไม่ใช่คำตอบเดียวสำหรับทุกปัญหา session
สำหรับการเรียกข้าม origin ต้องดูตัวเลือก credentials ของ fetch ร่วมด้วย หากตั้งให้รวม credentials ก็ยังไม่ข้ามข้อจำกัด SameSite ของ cookie และเมื่อเกี่ยวข้องกับ CORS ฝั่งบริการก็ต้องตอบการอนุญาตตามรูปแบบที่ใช้ ไม่ใช้ wildcard แทน origin ที่ต้องระบุชัด
ในทางตรวจจึงควรดูทั้งว่า browser แนบ Cookie ไปจริงหรือไม่ กับ script อ่าน response ได้หรือเปล่า เพราะบางคำขออาจถูกส่งออกแล้วแต่ผลไม่เปิดให้ JavaScript อ่าน หากมองเฉพาะ catch ฝั่งหน้าเว็บ ก็อาจแยกสองกรณีนี้ไม่ได้
เมื่อ cookie ถูกแนบแล้วแต่ API ยังตอบว่าไม่มี session ต้องตรวจฝั่งบริการต่อ เช่น หมดอายุ ไม่พบตัวระบุ หรือกำลังอ่านจากสภาพแวดล้อมคนละชุด ไม่ขยายขอบเขต cookie อีกทั้งที่ปัญหาอยู่หลังการรับแล้ว
ระบบที่อาศัย cookie สำหรับการยืนยันตัวตนต้องพิจารณา CSRF ตามสัญญาของการใช้งานด้วย เพราะ browser อาจแนบข้อมูลยืนยันตัวตนในคำขอที่เกิดจากบริบทอื่นได้ตามเงื่อนไข การมี session ถูกต้องจึงไม่ได้ตอบเองว่าผู้ใช้ตั้งใจสั่งผลนั้นผ่านช่องทางที่อนุญาต
SameSite เป็นชั้นหนึ่งที่ช่วยได้ตามบริบท แต่ควรใช้ร่วมกับกลไกที่เหมาะกับแอป เช่น การตรวจ token หรือข้อมูลต้นทางตามแนวทางที่ระบบเลือก ไม่ถือว่า HttpOnly หรือ CORS ทำหน้าที่ป้องกัน CSRF ทั้งหมดแทนกันได้
ชุดตรวจควรใช้บัญชีทดลอง ดูการเข้าใช้งานจากหน้าปกติ การเรียก API ข้าม origin การนำทางที่เกี่ยวข้อง และการออกจากระบบ โดยตรวจว่าการล้าง cookie อ้าง Domain กับ Path ที่ถูกต้อง และบริการยุติ session ตามนโยบายจริง ไม่รายงานจากการที่ปุ่ม login เปลี่ยนหน้าตาอย่างเดียว
Cookie ที่ทำงานได้ต้องผ่านทั้งการเก็บ ขอบเขตการส่งและการตรวจของบริการ เมื่อแยก Domain Path Secure HttpOnly SameSite กับ credentials ตามหน้าที่ เราจะตามปัญหา session ได้ตรงขั้นขึ้น พร้อมรักษาขอบเขตที่จำเป็นจริง การขยายค่าให้กว้างขึ้นจึงควรตามมาจากหลักฐานของเส้นทางที่ต้องรองรับ ไม่ใช่เพียงทำให้ข้อความผิดพลาดครั้งหนึ่งหายไป