logologo
เริ่มต้น
คู่มือ
การพัฒนา
ปลั๊กอิน
API
English
简体中文
日本語
한국어
Deutsch
Français
Español
Português
Русский
Italiano
Türkçe
Українська
Tiếng Việt
Bahasa Indonesia
ไทย
Polski
Nederlands
Čeština
العربية
עברית
हिन्दी
Svenska
เริ่มต้น
คู่มือ
การพัฒนา
ปลั๊กอิน
API
logologo

เริ่มต้นใช้งานฉบับย่อ

ภาพรวมการพัฒนาปลั๊กอิน
การเขียนปลั๊กอินแรกของคุณ
โครงสร้างไดเรกทอรีโปรเจกต์

การพัฒนาฝั่งเซิร์ฟเวอร์

ภาพรวม
ปลั๊กอิน
คอลเลกชัน
การดำเนินการฐานข้อมูล
การจัดการแหล่งข้อมูล
การจัดการทรัพยากร
การควบคุมการเข้าถึง (ACL)
มิดเดิลแวร์
แคช
เหตุการณ์
คอนเท็กซ์คำขอ
สคริปต์การย้ายข้อมูล
ล็อก
การทำให้เป็นสากล (I18n)
คำสั่ง
การจัดการงานที่กำหนดเวลา
การทดสอบ

การพัฒนาฝั่งไคลเอนต์

ภาพรวม
ปลั๊กอิน
คอนเท็กซ์
เราเตอร์
การควบคุมการเข้าถึง (ACL)
การจัดการแหล่งข้อมูล
ทรัพยากร
คำขอ
สไตล์และธีม
ล็อก
การทำให้เป็นสากล (I18n)
การทดสอบ

อื่นๆ

คู่มือการอัปเกรดปลั๊กอิน
รายการภาษา
การจัดการ Dependencies
การสร้าง
Previous Pageการจัดการทรัพยากร
Next Pageมิดเดิลแวร์
TIP

เอกสารนี้แปลโดย AI หากมีข้อมูลที่ไม่ถูกต้อง โปรดดูเวอร์ชันภาษาอังกฤษ

#การควบคุมสิทธิ์ ACL

ACL (Access Control List) ใช้สำหรับควบคุมสิทธิ์การเข้าถึงและการดำเนินการกับทรัพยากรต่างๆ ครับ/ค่ะ คุณสามารถกำหนดสิทธิ์ให้กับบทบาท (Role) หรือจะข้ามข้อจำกัดของบทบาทไปกำหนดสิทธิ์โดยตรงก็ได้ครับ/ค่ะ ระบบ ACL มีกลไกการจัดการสิทธิ์ที่ยืดหยุ่น รองรับวิธีการที่หลากหลาย เช่น การใช้ Permission Snippet, Middleware, การตรวจสอบเงื่อนไข และอื่นๆ ครับ/ค่ะ

ข้อควรทราบ

ออบเจกต์ ACL จะเป็นส่วนหนึ่งของแหล่งข้อมูล (dataSource.acl) ครับ/ค่ะ สำหรับ ACL ของแหล่งข้อมูลหลัก สามารถเข้าถึงได้อย่างรวดเร็วผ่าน app.acl ครับ/ค่ะ ส่วนการใช้งาน ACL ของแหล่งข้อมูลอื่นๆ สามารถดูรายละเอียดเพิ่มเติมได้ในบท การจัดการแหล่งข้อมูล ครับ/ค่ะ

#การลงทะเบียน Permission Snippet

Permission Snippet ช่วยให้คุณสามารถลงทะเบียนชุดสิทธิ์ที่ใช้งานบ่อยๆ ให้เป็นหน่วยสิทธิ์ที่นำกลับมาใช้ซ้ำได้ครับ/ค่ะ เมื่อบทบาทถูกผูกกับ Snippet ก็จะได้รับชุดสิทธิ์ที่เกี่ยวข้อง ซึ่งช่วยลดการตั้งค่าซ้ำซ้อนและเพิ่มประสิทธิภาพในการจัดการสิทธิ์ครับ/ค่ะ

acl.registerSnippet({
  name: 'ui.customRequests', // คำนำหน้า ui.* บ่งชี้ว่าสิทธิ์นี้สามารถกำหนดค่าได้บนหน้า UI
  actions: ['customRequests:*'], // การดำเนินการกับทรัพยากรที่เกี่ยวข้อง รองรับ Wildcard
});

#สิทธิ์ที่ข้ามข้อจำกัดของบทบาท (allow)

acl.allow() ใช้เพื่ออนุญาตให้การดำเนินการบางอย่างสามารถข้ามข้อจำกัดของบทบาทได้ เหมาะสำหรับ API สาธารณะ, สถานการณ์ที่ต้องการการตรวจสอบสิทธิ์แบบไดนามิก หรือกรณีที่ต้องตัดสินสิทธิ์โดยอิงจาก Context ของคำขอครับ/ค่ะ

// การเข้าถึงสาธารณะ ไม่ต้องล็อกอิน
acl.allow('app', 'getLang', 'public');

// ผู้ใช้ที่ล็อกอินแล้วสามารถเข้าถึงได้
acl.allow('app', 'getInfo', 'loggedIn');

// อิงตามเงื่อนไขที่กำหนดเอง
acl.allow('orders', ['create', 'update'], (ctx) => {
  return ctx.auth.user?.isAdmin ?? false;
});

คำอธิบายพารามิเตอร์ condition:

  • 'public': ผู้ใช้ทุกคน (รวมถึงผู้ที่ยังไม่ได้ล็อกอิน) สามารถเข้าถึงได้ โดยไม่จำเป็นต้องมีการยืนยันตัวตนใดๆ ครับ/ค่ะ
  • 'loggedIn': เฉพาะผู้ใช้ที่ล็อกอินแล้วเท่านั้นที่สามารถเข้าถึงได้ โดยต้องมีข้อมูลผู้ใช้ที่ถูกต้องครับ/ค่ะ
  • (ctx) => Promise<boolean> หรือ (ctx) => boolean: ฟังก์ชันที่กำหนดเอง ซึ่งจะตรวจสอบแบบไดนามิกจาก Context ของคำขอว่าอนุญาตให้เข้าถึงหรือไม่ และสามารถนำไปใช้กับ Logic สิทธิ์ที่ซับซ้อนได้ครับ/ค่ะ

#การลงทะเบียน Permission Middleware (use)

acl.use() ใช้สำหรับลงทะเบียน Middleware สิทธิ์ที่กำหนดเอง ซึ่งสามารถแทรก Logic ที่กำหนดเองเข้าไปในขั้นตอนการตรวจสอบสิทธิ์ได้ครับ/ค่ะ โดยทั่วไปจะใช้ร่วมกับ ctx.permission เพื่อกำหนดกฎสิทธิ์ที่กำหนดเองครับ/ค่ะ เหมาะสำหรับสถานการณ์ที่ต้องการการควบคุมสิทธิ์ที่ไม่ใช่แบบปกติ เช่น ฟอร์มสาธารณะที่ต้องมีการยืนยันรหัสผ่านที่กำหนดเอง, การตรวจสอบสิทธิ์แบบไดนามิกโดยอิงจากพารามิเตอร์ของคำขอ เป็นต้นครับ/ค่ะ

สถานการณ์การใช้งานทั่วไป:

  • สถานการณ์ฟอร์มสาธารณะ: ไม่มีผู้ใช้ ไม่มีบทบาท แต่ต้องการจำกัดสิทธิ์ด้วยรหัสผ่านที่กำหนดเอง
  • การควบคุมสิทธิ์โดยอิงจากพารามิเตอร์คำขอ, ที่อยู่ IP หรือเงื่อนไขอื่นๆ
  • กฎสิทธิ์ที่กำหนดเอง เพื่อข้ามหรือแก้ไขขั้นตอนการตรวจสอบสิทธิ์เริ่มต้น

การควบคุมสิทธิ์ผ่าน ctx.permission:

acl.use(async (ctx, next) => {
  const { resourceName, actionName } = ctx.action;
  
  // ตัวอย่าง: ฟอร์มสาธารณะที่ต้องมีการยืนยันรหัสผ่านก่อนจึงจะข้ามการตรวจสอบสิทธิ์ได้
  if (resourceName === 'publicForms' && actionName === 'submit') {
    const password = ctx.request.body?.password;
    if (password === 'your-secret-password') {
      // ยืนยันสำเร็จ ข้ามการตรวจสอบสิทธิ์
      ctx.permission = {
        skip: true,
      };
    } else {
      ctx.throw(403, 'Invalid password');
    }
  }
  
  // ดำเนินการตรวจสอบสิทธิ์ (ดำเนินการตามขั้นตอน ACL ต่อไป)
  await next();
});

คำอธิบายคุณสมบัติ ctx.permission:

  • skip: true: ข้ามการตรวจสอบสิทธิ์ ACL ที่เหลือ และอนุญาตให้เข้าถึงได้ทันที
  • สามารถตั้งค่าแบบไดนามิกใน Middleware ตาม Logic ที่กำหนดเอง เพื่อให้การควบคุมสิทธิ์มีความยืดหยุ่น

#การเพิ่มข้อจำกัดข้อมูลแบบตายตัวสำหรับการดำเนินการเฉพาะ (addFixedParams)

addFixedParams สามารถเพิ่มข้อจำกัดขอบเขตข้อมูล (filter) แบบตายตัวให้กับการดำเนินการของทรัพยากรบางอย่างได้ ข้อจำกัดเหล่านี้จะข้ามข้อจำกัดของบทบาทและถูกนำไปใช้โดยตรง ซึ่งมักใช้เพื่อปกป้องข้อมูลสำคัญของระบบครับ/ค่ะ

acl.addFixedParams('roles', 'destroy', () => {
  return {
    filter: {
      $and: [
        { 'name.$ne': 'root' },
        { 'name.$ne': 'admin' },
        { 'name.$ne': 'member' },
      ],
    },
  };
});

// แม้ผู้ใช้จะมีสิทธิ์ลบบทบาท แต่ก็ไม่สามารถลบบทบาทระบบ เช่น root, admin, member ได้ครับ/ค่ะ

เคล็ดลับ: addFixedParams สามารถใช้เพื่อป้องกันข้อมูลที่ละเอียดอ่อนถูกลบหรือแก้ไขโดยไม่ตั้งใจ เช่น บทบาทที่มาพร้อมกับระบบ, บัญชีผู้ดูแลระบบ เป็นต้นครับ/ค่ะ ข้อจำกัดเหล่านี้จะทำงานร่วมกับสิทธิ์ของบทบาท เพื่อให้แน่ใจว่าแม้จะมีสิทธิ์ก็ไม่สามารถดำเนินการกับข้อมูลที่ได้รับการปกป้องได้ครับ/ค่ะ

#การตรวจสอบสิทธิ์ (can)

acl.can() ใช้สำหรับตรวจสอบว่าบทบาทใดมีสิทธิ์ดำเนินการตามที่ระบุหรือไม่ โดยจะคืนค่าเป็นออบเจกต์ผลลัพธ์ของสิทธิ์ หรือ null ครับ/ค่ะ มักใช้ในการตรวจสอบสิทธิ์แบบไดนามิกใน Logic ทางธุรกิจ เช่น การตัดสินใจว่าจะอนุญาตให้ดำเนินการบางอย่างหรือไม่ โดยอิงจากบทบาทใน Middleware หรือ Handler ของการดำเนินการนั้นๆ ครับ/ค่ะ

const result = acl.can({
  roles: ['admin', 'manager'], // สามารถส่งบทบาทเดียวหรืออาร์เรย์ของบทบาทได้
  resource: 'orders',
  action: 'delete',
});

if (result) {
  console.log(`บทบาท ${result.role} สามารถดำเนินการ ${result.action} ได้ครับ/ค่ะ`);
  // result.params มีพารามิเตอร์แบบตายตัวที่ตั้งค่าผ่าน addFixedParams
  console.log('พารามิเตอร์แบบตายตัว:', result.params);
} else {
  console.log('ไม่มีสิทธิ์ดำเนินการนี้ครับ/ค่ะ');
}

เคล็ดลับ: หากมีการส่งบทบาทหลายบทบาท ระบบจะตรวจสอบแต่ละบทบาทตามลำดับ และจะคืนค่าผลลัพธ์ที่เป็นการรวมกันของสิทธิ์จากบทบาทเหล่านั้นครับ/ค่ะ

คำจำกัดความประเภท (Type Definitions):

interface CanArgs {
  role?: string;      // บทบาทเดียว
  roles?: string[];   // หลายบทบาท (จะตรวจสอบตามลำดับ และคืนค่าบทบาทแรกที่มีสิทธิ์)
  resource: string;   // ชื่อทรัพยากร
  action: string;    // ชื่อการดำเนินการ
}

interface CanResult {
  role: string;       // บทบาทที่มีสิทธิ์
  resource: string;   // ชื่อทรัพยากร
  action: string;    // ชื่อการดำเนินการ
  params?: any;       // ข้อมูลพารามิเตอร์แบบตายตัว (หากมีการตั้งค่าผ่าน addFixedParams)
}

#การลงทะเบียนการดำเนินการที่กำหนดค่าได้ (setAvailableAction)

หากคุณต้องการให้การดำเนินการที่กำหนดเองสามารถกำหนดค่าสิทธิ์ได้บนหน้า UI (เช่น แสดงในหน้าจัดการบทบาท) คุณจะต้องใช้ setAvailableAction เพื่อลงทะเบียนครับ/ค่ะ การดำเนินการที่ลงทะเบียนแล้วจะปรากฏในหน้าการกำหนดค่าสิทธิ์ ซึ่งผู้ดูแลระบบสามารถกำหนดสิทธิ์การดำเนินการสำหรับบทบาทต่างๆ ได้บนหน้า UI ครับ/ค่ะ

acl.setAvailableAction('importXlsx', {
  displayName: '{{t("Import")}}', // ชื่อที่แสดงบน UI รองรับการแปลหลายภาษา (Internationalization)
  type: 'new-data',               // ประเภทการดำเนินการ
  onNewRecord: true,              // มีผลเมื่อสร้างเรคคอร์ดใหม่หรือไม่
});

คำอธิบายพารามิเตอร์:

  • displayName: ชื่อที่แสดงในหน้าการกำหนดค่าสิทธิ์ รองรับการแปลหลายภาษา (Internationalization) (ใช้รูปแบบ {{t("key")}})
  • type: ประเภทการดำเนินการ ซึ่งกำหนดการจัดหมวดหมู่ของการดำเนินการนี้ในการกำหนดค่าสิทธิ์
    • 'new-data': การดำเนินการที่สร้างข้อมูลใหม่ (เช่น การนำเข้า, การเพิ่มข้อมูลใหม่ เป็นต้น)
    • 'existing-data': การดำเนินการที่แก้ไขข้อมูลที่มีอยู่ (เช่น การอัปเดต, การลบ เป็นต้น)
  • onNewRecord: มีผลเมื่อสร้างเรคคอร์ดใหม่หรือไม่ ซึ่งใช้ได้เฉพาะกับประเภท 'new-data' เท่านั้น

หลังจากลงทะเบียนแล้ว การดำเนินการนี้จะปรากฏในหน้าการกำหนดค่าสิทธิ์ ซึ่งผู้ดูแลระบบสามารถกำหนดสิทธิ์ของการดำเนินการนี้ได้ในหน้าจัดการบทบาทครับ/ค่ะ