AWS สำหรับมือใหม่: S3, Deduplication และ Presigned URLs

เลิกสร้างแอปเล่นๆ แล้วเริ่มสร้างระบบที่ใช้งานจริง (production) ได้เสียที

หากเซิร์ฟเวอร์ของคุณเป็นแบบใช้งานแล้วทิ้ง (disposable) ไฟล์ของคุณก็ไม่ควรเก็บไว้ในดิสก์ของเซิร์ฟเวอร์นั้น คุณจำเป็นต้องใช้ AWS S3 ซึ่งเป็น Object Storage ที่ทำงานแยกจากเซิร์ฟเวอร์ของคุณโดยอิสระ สิ่งนี้ช่วยให้มั่นใจได้ว่าไฟล์ของคุณจะยังคงอยู่แม้ว่าเซิร์ฟเวอร์จะล่มหรือหายไปก็ตาม

นี่คือวิธีการสร้างขั้นตอนการอัปโหลดไฟล์แบบมืออาชีพ:

  • ใช้ S3 Buckets และ Keys Bucket คือคอนเทนเนอร์ของคุณ ส่วน Key คือเส้นทาง (path) เต็มของไฟล์ S3 ไม่มีโฟลเดอร์จริงๆ แต่จะใช้ prefix ในโครงสร้างแบบแบน (flat structure) คุณสามารถจัดระเบียบไฟล์ตามประเภทได้ เช่น images/ หรือ documents/ เพื่อให้ข้อมูลเป็นระเบียบ

  • ทำ Content Deduplication อย่าจ่ายเงินซ้ำซ้อนสำหรับไฟล์เดิม ให้ใช้อัลกอริทึม SHA-256 เพื่อสร้างลายนิ้วมือ (fingerprint) ที่ไม่ซ้ำกันสำหรับทุกไฟล์ หากผู้ใช้สองคนอัปโหลดรูปภาพที่เหมือนกันทุกประการ ค่า hash จะเหมือนกัน ให้ตรวจสอบ hash นี้ในฐานข้อมูลของคุณก่อนที่จะอัปโหลดไปยัง S3 หากพบ hash นี้อยู่แล้ว ให้ใช้ไฟล์เดิมที่มีอยู่ได้เลย

  • ใช้การ Stream สำหรับไฟล์ขนาดใหญ่ อย่าโหลดวิดีโอขนาด 200MB เข้าไปใน RAM ของเซิร์ฟเวอร์เพียงเพื่อจะทำ hash ให้ใช้ Node.js streams ในการประมวลผลไฟล์เป็นส่วนเล็กๆ (chunks) วิธีนี้จะช่วยให้เซิร์ฟเวอร์ของคุณทำงานได้รวดเร็วและป้องกันการล่ม

  • กำหนดขีดจำกัดขนาดไฟล์ การตรวจสอบที่ฝั่ง Frontend มีไว้เพื่อประสบการณ์การใช้งาน (UX) เท่านั้น ไม่ใช่เรื่องความปลอดภัย คุณต้องบังคับใช้ขีดจำกัดขนาดไฟล์ใน 3 ระดับ: • ฝั่ง Client เพื่อ UX • การตรวจสอบที่ Backend เพื่อปฏิเสธคำขอที่ไม่ถูกต้องตั้งแต่เนิ่นๆ • เงื่อนไขของ S3 ผ่าน presigned URLs เพื่อหยุดการอัปโหลดที่มีขนาดใหญ่เกินไปตั้งแต่ต้นทาง

  • ใช้ Presigned URLs เพื่อความปลอดภัย อย่าตั้งค่า Bucket ของคุณเป็นสาธารณะ (public) ให้เปิดใช้งาน "Block all public access" ไว้เสมอ แต่ให้ใช้วิธีสร้าง presigned URL แทน ซึ่งจะให้สิทธิ์ผู้ใช้ชั่วคราวในการอัปโหลดไฟล์เฉพาะเจาะจงเพียงไฟล์เดียว คุณสามารถกำหนดเวลาหมดอายุได้ โดยควรใช้ช่วงเวลาสั้นๆ สำหรับไฟล์ขนาดเล็ก และใช้ช่วงเวลาที่นานขึ้นสำหรับการอัปโหลดวิดีโอขนาดใหญ่

  • ตรวจสอบการอัปโหลด อย่าเชื่อใจฝั่ง Client เพียงอย่างเดียว หลังจากอัปโหลดเสร็จแล้ว ให้ใช้คำสั่ง HeadObject เพื่อตรวจสอบว่าไฟล์มีอยู่ใน S3 จริงหรือไม่ และขนาดไฟล์ตรงกับข้อมูลที่คุณบันทึกไว้หรือไม่

ขั้นตอนการทำงานในระบบจริง (Production Flow):

  1. Client ร้องขอ URL สำหรับการอัปโหลด
  2. Backend ตรวจสอบขนาด ประเภท และเช็คไฟล์ซ้ำ
  3. Backend สร้าง presigned URL ที่มีการจำกัดขอบเขต (scoped)
  4. Client อัปโหลดไฟล์ไปยัง S3 โดยตรง
  5. Backend ยืนยันว่าไฟล์มีอยู่จริงผ่าน HeadObject

จงสร้างระบบที่มีความปลอดภัยตั้งแต่เริ่มต้น (secure by default)

ที่มา: https://dev.to/surajrkhonde/aws-for-newbies-episode-2-3jg5