Auth0 & OTP Flows (ระบบยืนยันตัวตนและการป้องกันความปลอดภัย)
หน้านี้อธิบายสถาปัตยกรรมระบบการยืนยันตัวตน (Authentication) การสมัครสมาชิก และระบบรักษาความปลอดภัยในการส่งรหัสผ่านครั้งเดียว (OTP) โดยเชื่อมโยงระหว่างระบบ Next.js Frontend, Auth0 (Identity Provider), Cloudflare, Redis และ Twilio
1. การเชื่อมต่อข้อมูลสิทธิ์ในระบบ (Auth0 Post-Login Action)
เมื่อผู้ใช้งาน (ทั้งเจ้าหน้าที่ Backoffice และลูกค้าทั่วไป) ล็อกอินผ่าน Auth0 สำเร็จ ระบบจะเรียกรัน Post-Login Action เพื่อตรวจสอบประเภทผู้ใช้งานและซิงก์รหัสผู้ใช้ภายใน (Internal User ID) เข้ากับ JWT Token สำหรับใช้ในการระบุตัวตนในระบบ Microservices
📸 ขั้นตอนการระบุตัวตน (Auth0 Post-Login Flow)
2. ขั้นตอนการสมัครและล็อกอินผ่าน OTP (Passwordless Login & Register)
ลูกค้าสามารถเข้าสู่ระบบผ่านอีเมลหรือเบอร์โทรศัพท์ (Passwordless) ได้โดยไม่ต้องใช้รหัสผ่าน หากเป็นผู้ใช้ใหม่ ระบบจะบังคับให้อ่านและยอมรับนโยบายความเป็นส่วนตัวและข้อตกลงการใช้งาน (Terms & Conditions) ก่อนสร้างบัญชีลงในฐานข้อมูลหลัก
📸 ขั้นตอนการทำงานจริง (Passwordless Sequence)
3. ท่อป้องกันความปลอดภัยหลายชั้น (Multi-Layer Security Pipeline)
เพื่อป้องกันปัญหาการสแปม OTP (OTP Spamming) จากสคริปต์บอท หรือการพยายามโจมตีระบบ ระบบจึงติดตั้งมาตรการป้องกันความปลอดภัย 4 ชั้น:
🛡️ รายละเอียดระบบการป้องกันในแต่ละชั้น:
1. Blacklisted / Inactive Cookie Prevention (ชั้นคุกกี้บล็อก)
- พฤติกรรม: หากผู้ใช้พยายามล็อกอินด้วยอีเมล/เบอร์โทรศัพท์ที่ถูกแบน (Blacklisted) หรือถูกระงับสิทธิ์ (Inactive) ในระบบหลัก และระบบตรวจพบหลังจากที่เขายืนยัน OTP ผ่านแล้ว
- มาตรการ: เซิร์ฟเวอร์จะฝังคุกกี้บล็อกอายุ 10 นาที ไว้ที่เบราว์เซอร์ของลูกค้า การขอ OTP ในครั้งต่อๆ ไปของข้อมูลผู้ใช้นี้จะถูกปฏิเสธทันทีก่อนการเรียกบริการอื่นใด เพื่อไม่ให้เกิดค่าใช้จ่าย SMS และรักษาข้อมูลระบบไม่ให้หลุดออกไป
2. Cloudflare Turnstile Verification (ชั้นสกัดบอท)
- พฤติกรรม: ฝั่ง Client ต้องแสดงและแก้โจทย์ Turnstile Widget เพื่อรับ Token ส่งมาพร้อมกับ API ขอ OTP
- มาตรการ: เซิร์ฟเวอร์จะทำการยืนยันความถูกต้องของ Token ไปยัง Cloudflare API หากไม่ผ่านจะถูกสกัดทิ้งทันที
3. OTP Rate Limiting via Redis (ชั้นจำกัดความถี่)
ระบบจัดเก็บประวัติการพยายามส่ง OTP ไว้ใน Redis Key: otp_attempt:{email/phone} อายุข้อมูล (TTL) 3 นาที โดยมีเกณฑ์การตรวจสอบดังนี้:
| พฤติกรรมการพยายาม (Attempts) | กฎเกณฑ์การทำงานของระบบ (Rate Limiting Rule) |
|---|---|
| ครั้งที่ 1 - 3 | อนุญาต: ระบบส่งรหัสผ่านให้ปกติ และบันทึกประวัติลง Redis พร้อมตั้งเวลา TTL 3 นาที |
| ครั้งที่ 4 - 6 | แจ้งเตือนความถี่: หากผู้ใช้ขอซ้ำในระยะเวลาอันสั้น ระบบจะทำการล็อกคำขอไว้จนกว่าจะครบ 10 นาที จึงจะรีเซ็ตประวัติ |
| ครั้งที่ 7 ขึ้นไป | ระงับการขอชั่วคราว: หากยังตรวจพบการพยายามขอซ้ำเข้ามาอีก ระบบจะล็อกคำขอนั้นไว้ยาวนาน 30 นาที จึงจะอนุญาตใหม่อีกครั้ง |
4. Twilio Fraud Guard (ชั้นวิเคราะห์พฤติกรรมเบอร์โทรศัพท์)
- พฤติกรรม: เมื่อผ่านสามด่านแรก ระบบจะส่งหมายเลขโทรศัพท์ไปตรวจสอบกับฐานข้อมูล Twilio
- มาตรการ: Twilio จะทำการคำนวณและประเมินระดับความเสี่ยงของหมายเลข (Risk Rating) เช่น เบอร์มาจากเครือข่ายที่มีการสแปมบ่อยครั้ง หรือเบอร์ชั่วคราว หากตรวจพบว่าเป็นกลุ่ม High Risk ระบบจะระงับการส่ง SMS เพื่อป้องกันค่าใช้จ่ายส่วนเกิน
4. โฟลว์การผูกบัญชี/อัปเดตข้อมูลผู้ติดต่อ (Profile OTP Linking Flow)
กรณีลูกค้าต้องการแก้ไขข้อมูลเบอร์โทรศัพท์หรืออีเมลหลักในหน้า /profile ระบบจะต้องส่ง OTP ไปพิสูจน์ความเป็นเจ้าของเบอร์/อีเมลใหม่นั้นก่อนบันทึกเข้าระบบ โดยการยืนยันตัวตนนี้จะต้องไม่ส่งผลกระทบต่อล็อกอินเซสชั่นในปัจจุบันของผู้ใช้
- เช็คข้อมูลซ้ำ (Uniqueness Check):
- ยิงคำขอ
GET /me/email/checkหรือGET /me/phone/checkเพื่อตรวจสอบล่วงหน้าว่า ข้อมูลใหม่ไม่ได้ถูกเชื่อมโยงอยู่กับบัญชีผู้อื่นในระบบ
- ยิงคำขอ
- ร้องขอรหัส OTP ในช่องทางใหม่ (Start Verification):
- เรียก API
POST /api/auth/passwordless/startเพื่อสั่งให้ Auth0 ส่งรหัสผ่าน OTP ไปยัง อีเมลใหม่ หรือเบอร์ใหม่ที่ระบุ
- เรียก API
- ตรวจสอบรหัส OTP (Verify Connection):
- เมื่อผู้ใช้ใส่รหัส ระบบจะส่งคำขอไปยัง
POST /api/auth/passwordless/verify-link - API ฝั่งเซิร์ฟเวอร์จะติดต่อกับ Auth0 เพื่อทำการแลกเปลี่ยนความถูกต้องและขอข้อมูล
auth0Id(จากฟิลด์subใน/userinfoของบัญชีใหม่)
- เมื่อผู้ใช้ใส่รหัส ระบบจะส่งคำขอไปยัง
- บันทึกการเชื่อมโยงข้อมูล (Update & Link):
- เมื่อได้
auth0Idที่ยืนยันความถูกต้องแล้ว Frontend จะเรียก APIPUT /me/emailหรือPUT /me/phoneพร้อมแนบauth0Idใหม่ไปอัปเดตข้อมูลในตารางCustomersของccr-user-service
- เมื่อได้