คีย์ API ลับในแอป Expo: อะไรต้องปกป้อง
โดย Mehdi Azizi
อัปเดตเมื่อ , 7 นาที
คีย์สาธารณะใส่ในแอปได้ แต่คีย์ลับต้องอยู่บนเซิร์ฟเวอร์เท่านั้น แล้วทดสอบสิทธิ์ด้วยบัญชีทดสอบสองบัญชี
ตัวแปรสภาพแวดล้อมไม่จำเป็นต้องเป็นความลับเสมอไป
ในแอป Expo ตัวแปรที่ขึ้นต้นด้วย EXPO_PUBLIC_ มีไว้ให้โค้ดของแอปใช้ จึงไม่ควรใส่ความลับของเซิร์ฟเวอร์ลงไป Expo อธิบายว่าค่าเหล่านี้จะถูกฝังอยู่ใน JavaScript ที่คอมไพล์แล้ว และผู้ใช้แอปสามารถอ่านได้ ดังนั้นการย้ายคีย์ไปไว้ในไฟล์ .env จึงไม่พอที่จะปกป้องมัน ที่มา: ตัวแปรสภาพแวดล้อมของ Expo
ก่อนจะสั่ง AI ให้ "ต่อ API" ให้คุณแยกประเภทสิ่งที่คุณจะมอบให้มันก่อน: ที่อยู่ของบริการ คีย์ที่ออกแบบมาให้เป็นสาธารณะ หรือคีย์ที่อนุญาตให้ทำสิ่งที่ต้องใช้สิทธิ์พิเศษ การแยกประเภทนี้จะเป็นตัวกำหนดว่าโค้ดต้องทำงานที่ไหน
ตารางต่อไปนี้เป็นแนวทางสำหรับการออกแบบ ไม่ใช่การตรวจสอบแอปของคุณ
| องค์ประกอบ | ควรเก็บไว้ที่ไหน | สิ่งที่ต้องตรวจสอบ |
|---|---|---|
| ที่อยู่สาธารณะของ backend | การตั้งค่าของแอป | ชี้ไปยังสภาพแวดล้อมที่ถูกต้อง |
| คีย์ Supabase publishable หรือคีย์ anon แบบเก่า | ในแอปได้ ถ้าตั้งค่าสิทธิ์ไว้ถูกต้อง | กฎของข้อมูลบล็อกการเข้าถึงบัญชีของผู้ใช้คนอื่นได้จริง |
| คีย์ Supabase secret หรือ service_role | บนเซิร์ฟเวอร์เท่านั้น | ไม่ปรากฏทั้งใน bundle ของแอปมือถือ และใน log ที่ฝั่ง client เข้าถึงได้ |
| คีย์ลับของผู้ให้บริการ AI | บนเซิร์ฟเวอร์เท่านั้น | แอปเรียกเซิร์ฟเวอร์ของคุณ ซึ่งตรวจสอบผู้ใช้และขีดจำกัดก่อนเรียกผู้ให้บริการ |
Supabase แยกคีย์ที่ออกแบบมาให้ client ใช้ ออกจากคีย์ลับที่มีไว้สำหรับสภาพแวดล้อมที่เชื่อถือได้ คีย์สาธารณะใช้ระบุโปรเจกต์ แต่ไม่ได้ทดแทนการกำหนดสิทธิ์ของข้อมูล ที่มา: คีย์ API ของ Supabase
ตัวอย่าง: แอปบันทึกการอ่านหนังสือสมมติ
สมมติว่ามีแอปที่ลีอาและซามีใช้บันทึกหนังสือและโน้ตส่วนตัวของตัวเอง ตัวอย่างนี้มีไว้เพื่อเตรียมการทดสอบ ไม่ได้อธิบายผลลัพธ์ที่ได้จากแอปของ Devoria
เส้นทางการใช้งานปกติดูเหมือนจะถูกต้อง: ลีอาล็อกอินแล้วเห็นโน้ตของตัวเอง แต่นั่นยังไม่ได้ตอบคำถามสำคัญ: เซิร์ฟเวอร์ปฏิเสธคำขอของลีอาที่พยายามเข้าถึงโน้ตของซามีหรือไม่?
ตัวกรองในหน้าจอ เช่น "แสดงโน้ตของผู้ใช้ที่ล็อกอินอยู่" ช่วยให้การแสดงผลดีขึ้น แต่การกำหนดสิทธิ์ต้องบังคับใช้ที่ฝั่งข้อมูลด้วย ใน Supabase กฎ Row Level Security ช่วยจำกัดแถวที่เข้าถึงได้ตาม session Supabase แนะนำให้เปิดใช้กับตารางที่เปิดผ่าน API และอธิบายนโยบายการอ่านและการเขียนไว้ ที่มา: Row Level Security
สำหรับโปรเจกต์ทดสอบของคุณเอง ให้ผูกโน้ตแต่ละรายการกับเจ้าของ แล้วกำหนดแยกกันว่าใครอ่าน สร้าง แก้ไข และลบได้ ตรวจสอบไฟล์ด้วย: การปกป้องแถวในฐานข้อมูลไม่ได้พิสูจน์ว่ารูปภาพเป็นส่วนตัว
ขั้นตอนทดสอบด้วยบัญชีทดสอบสองบัญชี
เตรียมบัญชีสองบัญชีที่คุณควบคุมได้ ใส่หนังสือคนละเล่มในแต่ละบัญชี และโน้ตสั้น ๆ ที่จำได้ง่าย ใช้ข้อมูลสมมติในสภาพแวดล้อมทดสอบที่ได้รับอนุญาต
- อ่านโน้ตของตัวเอง บัญชี A เห็นโน้ต A
- อ่านโน้ตของ B จากบัญชี A คำขอไม่เปิดเผยเนื้อหาส่วนตัว
- แก้ไขโน้ตของ B จากบัญชี A เซิร์ฟเวอร์ปฏิเสธ และโน้ต B ไม่เปลี่ยนแปลง
- สร้างข้อมูลในนามของ B จากบัญชี A เซิร์ฟเวอร์ปฏิเสธการระบุเจ้าของนี้
- อ่านโดยไม่มี session ไม่มีเนื้อหาส่วนตัวถูกส่งกลับมา
- เปิดไฟล์ส่วนตัวของ B จากบัญชี A เข้าถึงไฟล์ไม่ได้
จดผลลัพธ์จริง เวอร์ชันที่ทดสอบ และข้อผิดพลาด (ถ้ามี) "เปิดกฎไว้แล้ว" ไม่ใช่ผลการทดสอบ แบบฟอร์มทดสอบในหน้าแหล่งข้อมูล ใช้เป็นจุดเริ่มต้นสำหรับเก็บหลักฐานเหล่านี้ได้
ให้การเรียกที่มีค่าใช้จ่ายผ่านเซิร์ฟเวอร์ของคุณ
สำหรับฟีเจอร์สรุปหนังสือด้วยAPI ของ AI เส้นทางอาจเป็น: แอป → เซิร์ฟเวอร์ของคุณ → ผู้ให้บริการ → เซิร์ฟเวอร์ของคุณ → แอป คีย์ลับจะอยู่บนเซิร์ฟเวอร์ แต่สถาปัตยกรรมนี้อย่างเดียวยังไม่พอ: การเข้าถึงเซิร์ฟเวอร์ก็ต้องถูกควบคุมด้วย
ในตัวอย่างสมมตินี้ เซิร์ฟเวอร์ต้องตรวจสอบ session ตรวจสอบว่าหนังสือเป็นของผู้ใช้คนนั้น จำกัดคำขอที่ส่งซ้ำ ๆ และส่งข้อผิดพลาดที่เข้าใจได้กลับไปถ้าผู้ให้บริการไม่ตอบสนอง ฝั่ง client ไม่ได้เป็นผู้ตัดสินเองว่าผู้ใช้มีสิทธิ์ใช้ฟีเจอร์แบบเสียเงิน
เตรียมการทดสอบสี่แบบ: ผู้ใช้ที่ไม่ได้ล็อกอิน หนังสือของบัญชีอื่น ถึงขีดจำกัดแล้ว และผู้ให้บริการใช้งานไม่ได้ แบบสุดท้ายช่วยยืนยันว่าแอปออกจากสถานะกำลังโหลดได้โดยไม่ทำให้ข้อความที่ผู้ใช้พิมพ์ไว้หายไป
สิ่งที่คุณขอให้ผู้ช่วยเขียนโค้ดทำได้
นี่คือคำสั่งสำหรับรีวิวที่คุณปรับใช้กับ repository ของคุณได้ โดยไม่ต้องแปะค่าความลับลงไป:
ทำรายการตัวแปรที่ใช้ในโค้ดแอปมือถือและในเซิร์ฟเวอร์ โดยแสดงเฉพาะชื่อเท่านั้น ระบุการเรียกที่ต้องใช้สิทธิ์พิเศษที่อยู่ฝั่ง client สำหรับข้อมูลส่วนตัว ให้อธิบายการควบคุมการอ่านและการเขียน แล้วเสนอขั้นตอนทดสอบด้วยบัญชีทดสอบสองบัญชี ห้ามหมุนเวียนคีย์หรือแก้ไข production ใด ๆ โดยไม่ได้รับการอนุมัติ
อ่านคำตอบควบคู่กับโค้ดที่เกี่ยวข้อง ผู้ช่วยอาจพบจุดที่ไม่สอดคล้องกัน แต่คำตอบของมันไม่ได้ทดแทนการรันการทดสอบจริง คู่มือสร้างแอปด้วย Claude Code อธิบายวิธีแบ่งงานนี้เป็นส่วน ๆ
ก่อนพัฒนาแอปต่อ
คุณต้องอธิบายสามเรื่องได้อย่างง่าย ๆ: ค่าไหนเป็นสาธารณะ การทำงานไหนต้องผ่านเซิร์ฟเวอร์ และการทดสอบไหนแสดงว่าบัญชีหนึ่งมองไม่เห็นข้อมูลของอีกบัญชี ถ้ายังมีข้อไหนไม่ชัดเจน ให้ทำให้ชัดก่อนเพิ่มฟีเจอร์
หน้าสร้างแอป iPhone อธิบายว่าขั้นตอนนี้อยู่ตรงไหนของโปรเจกต์ทั้งหมด ถ้าอยากทำตามลำดับ iOS Kit มีเส้นทางสี่ขั้นตอนและโค้ดเริ่มต้นที่มีระบบบัญชีผู้ใช้และ AI อยู่แล้ว ถ้าคุณไม่แน่ใจว่าจะกลับไปเริ่มต่อที่ขั้นไหน แบบประเมินฟรี จะช่วยจัดลำดับโปรเจกต์ของคุณ และส่งเช็กลิสต์ป้องกันการถูก Apple ปฏิเสธของผมไปให้คุณ
คำถามที่พบบ่อย
ควรเก็บคีย์ API ลับไว้ที่ไหนในแอป Expo?
บนเซิร์ฟเวอร์ของคุณ ไม่ใช่ในแอปเด็ดขาด คีย์ Supabase secret หรือ service_role รวมถึงคีย์ลับของผู้ให้บริการ AI ต้องอยู่ฝั่งเซิร์ฟเวอร์เท่านั้น แอปเรียกเซิร์ฟเวอร์ของคุณ ซึ่งตรวจสอบผู้ใช้และขีดจำกัดก่อนเรียกผู้ให้บริการ ตรวจสอบให้แน่ใจว่าไม่มีคีย์เหล่านี้ปรากฏใน bundle ของแอปมือถือ หรือใน log ที่ฝั่ง client เข้าถึงได้
ไฟล์ .env ปกป้องคีย์ API ใน Expo ได้ไหม?
ลำพังไฟล์นี้อย่างเดียวไม่ได้ ตัวแปรที่ขึ้นต้นด้วย EXPO_PUBLIC_ มีไว้ให้โค้ดของแอปใช้ และไม่ควรมีความลับของเซิร์ฟเวอร์ Expo อธิบายว่าค่าเหล่านี้ถูกฝังใน JavaScript ที่คอมไพล์แล้ว และผู้ใช้แอปอ่านได้ ดังนั้นการย้ายคีย์ไปไว้ในไฟล์ .env จึงไม่พอที่จะปกป้องมัน
คีย์ API สาธารณะกับคีย์ลับต่างกันอย่างไร?
คีย์สาธารณะออกแบบมาให้ใส่ไปกับแอปได้: ใช้ระบุโปรเจกต์ แต่ไม่ได้ทดแทนการกำหนดสิทธิ์ของข้อมูล คีย์ลับอนุญาตให้ทำสิ่งที่ต้องใช้สิทธิ์พิเศษ และสงวนไว้สำหรับสภาพแวดล้อมที่เชื่อถือได้ ใน Supabase คีย์ publishable หรือคีย์ anon แบบเก่า อยู่ในแอปได้ถ้าตั้งค่าสิทธิ์ไว้ถูกต้อง ส่วนคีย์ secret และ service_role ต้องอยู่บนเซิร์ฟเวอร์
จะเรียก API ของ AI จากแอป Expo โดยไม่เปิดเผยคีย์ได้อย่างไร?
ให้การเรียกผ่านเซิร์ฟเวอร์ของคุณ: แอปเรียกเซิร์ฟเวอร์ เซิร์ฟเวอร์เรียกผู้ให้บริการ แล้วส่งคำตอบกลับไปที่แอป คีย์ลับจะอยู่บนเซิร์ฟเวอร์ เซิร์ฟเวอร์ยังต้องตรวจสอบ session จำกัดคำขอที่ส่งซ้ำ ๆ และส่งข้อผิดพลาดที่เข้าใจได้กลับไปถ้าผู้ให้บริการไม่ตอบสนอง ฝั่ง client ไม่ได้เป็นผู้ตัดสินเองว่าผู้ใช้มีสิทธิ์ใช้ฟีเจอร์แบบเสียเงิน
จะตรวจสอบได้อย่างไรว่าผู้ใช้แต่ละคนเห็นเฉพาะข้อมูลของตัวเอง?
เตรียมบัญชีทดสอบสองบัญชีที่คุณควบคุมได้ โดยมีโน้ตที่จำได้ง่ายในแต่ละบัญชี จากบัญชี A ลองอ่าน แก้ไข และสร้างข้อมูลในนามของบัญชี B แล้วลองเปิดไฟล์ส่วนตัวของ B ทดสอบแบบไม่มี session ด้วย: ทุกคำขอต้องถูกปฏิเสธหรือไม่เปิดเผยอะไรเลย จดผลลัพธ์จริงไว้ เพราะ "เปิดกฎไว้แล้ว" ไม่ใช่ผลการทดสอบ
จะให้ AI ตรวจสอบคีย์ในแอปของฉันได้อย่างไร?
ขอให้มันทำรายการตัวแปรในโค้ดแอปมือถือและเซิร์ฟเวอร์ โดยแสดงเฉพาะชื่อ และไม่ต้องแปะค่าความลับของคุณลงไป ขอให้มันระบุการเรียกที่ต้องใช้สิทธิ์พิเศษที่อยู่ฝั่ง client และเสนอขั้นตอนทดสอบด้วยบัญชีทดสอบสองบัญชีด้วย ห้ามไม่ให้หมุนเวียนคีย์หรือแก้ไข production โดยไม่ได้รับการอนุมัติ คำตอบของมันไม่ได้ทดแทนการรันการทดสอบจริง