ข้ามไปยังเนื้อหาหลัก

คำขอ Webhooks

เมื่อเหตุการณ์ webhook ถูกเรียกใช้ Logto จะส่งคำขอ POST ไปยังทุก endpoint ที่สมัครรับข้อมูลไว้ แคตตาล็อกเหตุการณ์ทั้งหมดอยู่ใน Webhooks events; หน้านี้เอกสาร รูปแบบของคำขอ ที่ Logto ส่ง

ส่วนหัวของคำขอ

Keyปรับแต่งได้หมายเหตุ
user-agentLogto (https://logto.io/) โดยค่าเริ่มต้น.
content-typeapplication/json โดยค่าเริ่มต้น.
logto-signature-sha-256ลายเซ็นของเนื้อหาคำขอ ดู securing your webhooks.

ส่วนหัวที่สามารถปรับแต่งได้สามารถถูกแทนที่ผ่านการตั้งค่า secure webhook.

ภาพรวมของเนื้อหาคำขอ

เนื้อหาเป็นวัตถุ JSON รูปแบบที่แน่นอนขึ้นอยู่กับว่ามันเป็นของครอบครัวเหตุการณ์ใด:

FamilyEventsWhen it fires
User flowPostRegister, PostSignIn, PostResetPasswordเมื่อผู้ใช้ทำกระบวนการลงทะเบียน ลงชื่อเข้าใช้ หรือรีเซ็ตรหัสผ่านที่จัดการโดย Experience API เสร็จสิ้น.
Data mutationUser.*, Role.*, Scope.*, Organization.*, OrganizationRole.*, OrganizationScope.*เมื่อโมเดลข้อมูลพื้นฐานถูกเปลี่ยนแปลง — โดยการเรียก Management API หรือโดยกระบวนการผู้ใช้บน Experience API.
ExceptionIdentifier.Lockoutเหตุการณ์ด้านความปลอดภัย — เช่น บัญชีถูกล็อกหลังจากพยายามยืนยันตัวตนล้มเหลวติดต่อกัน.

ทุกครอบครัวมีชุด common fields ร่วมกัน จากนั้นแต่ละครอบครัวจะเพิ่มฟิลด์บริบทคำขอของตัวเองพร้อมกับ payload เฉพาะเหตุการณ์

ฟิลด์ทั่วไป

มีอยู่ในทุกการส่งไม่ว่าจะเป็นครอบครัวใด:

FieldTypeOptionalNotes
hookIdstringตัวระบุการตั้งค่า webhook ใน Logto.
eventstringเหตุการณ์ที่กระตุ้นการส่งนี้.
createdAtstringเวลาสร้าง payload ในรูปแบบ ISO 8601.
userAgentstringตัวแทนผู้ใช้ของคำขอที่กระตุ้น.

แต่ละครอบครัวยังรวมถึงที่อยู่ IP ของคำขอที่กระตุ้น — ภายใต้ชื่อฟิลด์ userIp สำหรับเหตุการณ์ user-flow และ ip สำหรับเหตุการณ์ data-mutation และ exception ความหมายเหมือนกัน; ชื่อที่แตกต่างกันทางประวัติศาสตร์ถูกเก็บรักษาไว้เพื่อความเข้ากันได้ย้อนหลัง

Payload ของเหตุการณ์ User flow

Events: PostRegister, PostSignIn, PostResetPassword.

ถูกเรียกใช้เมื่อผู้ใช้ทำกระบวนการลงทะเบียน ลงชื่อเข้าใช้ หรือรีเซ็ตรหัสผ่านที่จัดการโดย Experience API เสร็จสิ้น นอกจาก common fields แล้ว เนื้อหายังมี:

FieldTypeOptionalNotes
interactionEvent'SignIn' | 'Register' | 'ForgotPassword'ประเภทเหตุการณ์ user-flow. แผนที่ไปยัง PostSignIn / PostRegister / PostResetPassword ตามลำดับ ชื่อฟิลด์ยังคงชื่อ "interaction" ทางประวัติศาสตร์.
sessionIdstringSession ID (ไม่ใช่ Interaction ID) สำหรับเหตุการณ์นี้ ถ้ามี.
userIpstringที่อยู่ IP ของคำขอที่กระตุ้น.
userIdstringUser ID ที่เกี่ยวข้องกับเหตุการณ์นี้ ถ้ามี.
userUserEntityเอนทิตีผู้ใช้ที่เกี่ยวข้องกับเหตุการณ์นี้ ถ้ามี.
applicationIdstringApplication ID ที่เกี่ยวข้องกับเหตุการณ์นี้ ถ้ามี.
applicationApplicationEntityเอนทิตีแอปพลิเคชันที่เกี่ยวข้องกับเหตุการณ์นี้ ถ้ามี.

รูปแบบเอนทิตี

type UserEntity = {
id: string;
username?: string;
primaryEmail?: string;
primaryPhone?: string;
name?: string;
avatar?: string;
customData?: object;
identities?: object;
lastSignInAt?: string;
createdAt?: string;
applicationId?: string;
isSuspended?: boolean;
};
enum ApplicationType {
Native = 'Native',
SPA = 'SPA',
Traditional = 'Traditional',
MachineToMachine = 'MachineToMachine',
Protected = 'Protected',
SAML = 'SAML',
}

type ApplicationEntity = {
id: string;
type: ApplicationType;
name: string;
description?: string;
};

ดู Users และ Applications สำหรับการอ้างอิงฟิลด์ทั้งหมด

Payload ของเหตุการณ์ Data mutation

Events: ทุกเหตุการณ์ภายใต้ User.*, Role.*, Scope.*, Organization.*, OrganizationRole.*, OrganizationScope.* — ดู Webhooks events → Data mutation hook events สำหรับแคตตาล็อกทั้งหมด

เนื้อหามักจะมี:

  • common fields.
  • ฟิลด์ ip — ที่อยู่ IP ของคำขอที่กระตุ้น (ไม่บังคับ, มีเมื่อทราบ).
  • บริบท API ที่อธิบายว่าการเปลี่ยนแปลงถูกกระตุ้นอย่างไร บริบทเป็นหนึ่งในสองรูปแบบขึ้นอยู่กับแหล่งที่มาของการกระตุ้น:
    • บริบท Experience API — เมื่อการเปลี่ยนแปลงมาจากกระบวนการที่ผู้ใช้เผชิญหน้า.
    • บริบท Management API — เมื่อการเปลี่ยนแปลงมาจากการเรียก Management API โดยตรง.
  • payload เฉพาะเหตุการณ์ — เอนทิตีที่ได้รับผลกระทบใน data และ (สำหรับบางเหตุการณ์) ฟิลด์ระดับบนเพิ่มเติม ดู payload ข้อมูลเฉพาะเหตุการณ์.

ฟิลด์บริบท Experience API

มีเมื่อการเปลี่ยนแปลงถูกกระตุ้นโดยกระบวนการที่ผู้ใช้เผชิญหน้าบน Experience API — ตัวอย่างเช่น, User.Created ระหว่างการลงทะเบียนหรือ User.Data.Updated ระหว่างการอัปเดตโปรไฟล์

FieldTypeOptionalNotes
interactionEvent'SignIn' | 'Register' | 'ForgotPassword'ประเภทเหตุการณ์ user-flow ที่ทำให้เกิดการเปลี่ยนแปลง ชื่อฟิลด์ยังคงชื่อ "interaction" ทางประวัติศาสตร์.
sessionIdstringSession ID (ไม่ใช่ Interaction ID) สำหรับเหตุการณ์นี้ ถ้ามี.
applicationIdstringApplication ID, ถ้ามี.
applicationApplicationEntityเอนทิตีแอปพลิเคชัน, ถ้ามี.

ฟิลด์บริบท Management API

มีเมื่อการเปลี่ยนแปลงถูกกระตุ้นโดยการเรียก Management API

FieldTypeOptionalNotes
pathstringเส้นทางของการเรียก API ที่กระตุ้น webhook นี้.
methodstringวิธี HTTP ของการเรียก API.
statusnumberรหัสสถานะการตอบสนองของการเรียก API.
paramsobjectพารามิเตอร์เส้นทาง koa ของการเรียก API.
matchedRoutestringเส้นทางที่ตรงกันของ koa Logto ใช้ฟิลด์นี้เพื่อจับคู่ตัวกรองเหตุการณ์ webhook ที่เปิดใช้งาน.

Payload ข้อมูลเฉพาะเหตุการณ์

ทุกเหตุการณ์ data-mutation รวมถึงฟิลด์ data ระดับบนที่มีเอนทิตีที่ได้รับผลกระทบ หรือ null เมื่อการเปลี่ยนแปลงไม่สามารถสรุปเป็นเอนทิตีเดียวได้ (เหตุการณ์ลบและสมาชิก) บางเหตุการณ์ยังรวมถึงฟิลด์ระดับบนเฉพาะเหตุการณ์นอกเหนือจาก dataOrganization.Membership.Updated เป็นกรณีหนึ่งที่มีการบันทึกไว้ด้านล่าง

เหตุการณ์ผู้ใช้

EventFieldTypeOptionalNotes
User.CreateddataUserEntityเอนทิตีผู้ใช้ที่สร้างขึ้น.
User.Data.UpdateddataUserEntityเอนทิตีผู้ใช้ที่อัปเดต.
User.Deleteddatanull/

เหตุการณ์บทบาท

type Role = {
id: string;
name: string;
description: string;
type: 'User' | 'MachineToMachine';
isDefault: boolean;
};
type Scope = {
id: string;
name: string;
description: string;
resourceId: string;
createdAt: number;
};
EventFieldTypeOptionalNotes
Role.CreateddataRoleเอนทิตีบทบาทที่สร้างขึ้น.
Role.Data.UpdateddataRoleเอนทิตีบทบาทที่อัปเดต.
Role.Deleteddatanull/
Role.Scopes.UpdateddataScope[]ขอบเขตที่อัปเดตที่กำหนดให้กับบทบาท.
Role.Scopes.UpdatedroleIdstringID บทบาทที่ขอบเขตถูกกำหนดให้ (มีเฉพาะเมื่อเหตุการณ์ถูกกระตุ้นโดยการสร้างบทบาทที่มีขอบเขตที่กำหนดล่วงหน้า).

เหตุการณ์สิทธิ์ (Scope)

EventFieldTypeOptionalNotes
Scope.CreateddataScopeเอนทิตีขอบเขตที่สร้างขึ้น.
Scope.Data.UpdateddataScopeเอนทิตีขอบเขตที่อัปเดต.
Scope.Deleteddatanull/

เหตุการณ์องค์กร

type Organization = {
id: string;
name: string;
description?: string;
customData: object;
createdAt: number;
};
EventFieldTypeOptionalNotes
Organization.CreateddataOrganizationเอนทิตีองค์กรที่สร้างขึ้น.
Organization.Data.UpdateddataOrganizationเอนทิตีองค์กรที่อัปเดต.
Organization.Deleteddatanull/
Organization.Membership.Updateddatanull/การเปลี่ยนแปลงถูกอธิบายโดยอาร์เรย์ delta ระดับบนที่เป็นทางเลือก ดู Organization.Membership.Updated payload ด้านล่าง.
Payload ของ Organization.Membership.Updated

นอกจากฟิลด์ทั่วไปและฟิลด์บริบท API ที่เหมาะสมตามแหล่งที่มาของทริกเกอร์ (บริบท Management API สำหรับเส้นทาง Management API, บริบท Experience API สำหรับการจัดเตรียมแบบทันเวลา) แล้ว เหตุการณ์ Organization.Membership.Updated ยังมี organizationId พร้อมอาร์เรย์ delta ที่เป็นทางเลือกที่ระดับบนของ payload (ถัดจาก event, createdAt, ฯลฯ, ไม่ใช่ ภายใน data, ซึ่งเป็น null เสมอสำหรับเหตุการณ์นี้)

FieldTypeOptionalNotes
organizationIdstringองค์กรที่การเป็นสมาชิกเปลี่ยนแปลง.
addedUserIdsstring[]User IDs ที่เพิ่มใหม่โดยการกระตุ้นนี้ ถูกละเว้นเมื่อไม่มีผู้ใช้ถูกเพิ่ม หรือเมื่อการกระตุ้นไม่ส่งผลต่อการเป็นสมาชิกของผู้ใช้.
removedUserIdsstring[]User IDs ที่ถูกลบโดยการกระตุ้นนี้ ถูกละเว้นเมื่อไม่มีผู้ใช้ถูกลบ.
addedApplicationIdsstring[]Application IDs ที่เพิ่มใหม่ ถูกละเว้นเมื่อไม่มีแอปพลิเคชันถูกเพิ่ม หรือเมื่อการกระตุ้นไม่ส่งผลต่อการเป็นสมาชิกของแอปพลิเคชัน.
removedApplicationIdsstring[]Application IDs ที่ถูกลบ ถูกละเว้นเมื่อไม่มีแอปพลิเคชันถูกลบ.

อาร์เรย์ delta ทั้งสี่เป็น ทางเลือกและเพิ่มเข้าไป — พวกมันไม่เปลี่ยนรูปแบบ payload ที่มีอยู่สำหรับผู้บริโภคที่ไม่คาดหวังพวกมัน และฟิลด์ data: null แบบดั้งเดิมยังคงถูกส่งออกโดยไม่เปลี่ยนแปลง

การกระตุ้นและฟิลด์ delta ที่พวกมันอาจส่งออก
TriggerPossible delta fields
POST /organizations/:id/usersaddedUserIds
PUT /organizations/:id/usersaddedUserIds, removedUserIds
DELETE /organizations/:id/users/:userIdremovedUserIds
POST /organizations/:id/applicationsaddedApplicationIds
PUT /organizations/:id/applicationsaddedApplicationIds, removedApplicationIds
DELETE /organizations/:id/applications/:applicationIdremovedApplicationIds
PUT /organization-invitations/:id/status (Accepted)addedUserIds
การจัดเตรียมแบบทันทีทันใด (Just-in-time) เมื่อเพิ่มผู้ใช้ในองค์กรใหม่addedUserIds
Delta ที่ว่างเปล่าถูกละเว้น — การไม่มี ≠ การเปลี่ยนแปลงที่ว่างเปล่า

อาร์เรย์ delta ที่ว่างเปล่า ถูกละเว้นทั้งหมด จาก payload ตัวอย่างเช่น, PUT /organizations/:id/users ที่แทนที่ชุดสมาชิกด้วยชุดที่มีอยู่แล้วไม่ก่อให้เกิดการเปลี่ยนแปลงจริง และ payload ลดลงเหลือเพียง { organizationId } โดยไม่มีฟิลด์ delta ทั้งสี่ การเดียวกันนี้ใช้กับการเพิ่มสมาชิกที่มีอยู่แล้ว การยอมรับคำเชิญซ้ำโดยผู้ใช้ที่เป็นสมาชิกอยู่แล้ว

ผู้บริโภคต้องถือว่าฟิลด์ที่หายไปหมายถึง "ไม่มีการเปลี่ยนแปลงในด้านนั้น" ไม่ใช่ "การเปลี่ยนแปลงที่ว่างเปล่า"

ขีดจำกัดต่ออาร์เรย์ (การตัดทอนอย่างเงียบ ๆ)

แต่ละอาร์เรย์ delta ถูกจำกัดที่ 5000 รายการ เมื่อการเรียก Management API เดียวเพิ่มหรือลบผู้ใช้ (หรือแอปพลิเคชัน) มากกว่า 5000 รายการในการดำเนินการเดียว อาร์เรย์ delta ที่สอดคล้องกันจะถูกตัดทอนอย่างเงียบ ๆ ไปยัง 5000 รายการแรกของมัน — ไม่มีตัวบ่งชี้ใน payload ว่าขีดจำกัดถูกเรียกใช้

หากแอปพลิเคชันของคุณดำเนินการบริหารจัดการแบบกลุ่มที่สามารถส่งผลกระทบต่อสมาชิกมากกว่า 5000 คนในการเรียกเดียว ให้ถือว่าอาร์เรย์ที่มี 5000 รายการพอดีเป็นสัญญาณให้กระทบยอดการเป็นสมาชิกที่มีอำนาจผ่าน Management API:

  • GET /organizations/:id/users — การเป็นสมาชิกผู้ใช้ทั้งหมด
  • GET /organizations/:id/applications — การเป็นสมาชิกแอปพลิเคชันทั้งหมด

สิ่งนี้เป็นไปตามรูปแบบเดียวกับเหตุการณ์ push ของ GitHub ซึ่งจำกัด commits ที่ 20 รายการและชี้ผู้บริโภคไปที่ API เปรียบเทียบสำหรับรายการทั้งหมด

ข้ามเหตุการณ์ที่ไม่มีการดำเนินการ

ทุก PUT ต่อเส้นทางการเป็นสมาชิกจะส่งเหตุการณ์ไม่ว่าจะมีการเปลี่ยนแปลงอะไรจริงหรือไม่ — เพื่อให้การเรียกแทนที่สถานะใด ๆ มีการส่ง webhook อย่างน้อยหนึ่งครั้งเพื่อวัตถุประสงค์ในการตรวจสอบ เพื่อข้ามการส่งที่ไม่มีการดำเนินการในฝั่งผู้บริโภค ให้กรองตามการมีอยู่ของอาร์เรย์ delta:

if (
payload.addedUserIds?.length ||
payload.removedUserIds?.length ||
payload.addedApplicationIds?.length ||
payload.removedApplicationIds?.length
) {
// การเปลี่ยนแปลงการเป็นสมาชิกจริง — จัดการมัน
}

?.length เป็นค่าเท็จสำหรับทั้ง undefined และ [], ดังนั้นคำทำนายเดียวกันนี้มีความทนทานไม่ว่าจะฟิลด์หายไปหรือ (ในอนาคตที่สมมุติ) ถูกส่งออกเป็นอาร์เรย์ว่างเปล่า

ตัวอย่าง payload

เพิ่มผู้ใช้ (POST /organizations/:id/users):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc",
"addedUserIds": ["u_001"]
}

แทนที่ชุดสมาชิกผู้ใช้ (PUT /organizations/:id/users):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc",
"addedUserIds": ["u_002"],
"removedUserIds": ["u_001"]
}

ลบผู้ใช้ (DELETE /organizations/:id/users/:userId):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc",
"removedUserIds": ["u_001"]
}

เพิ่มแอปพลิเคชัน (POST /organizations/:id/applications):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc",
"addedApplicationIds": ["app_xyz"]
}

เพิ่มสมาชิกที่มีอยู่แล้ว, no-op PUT, หรือการยอมรับคำเชิญซ้ำของสมาชิกที่มีอยู่แล้ว (ไม่มีการเปลี่ยนแปลงจริง):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc"
}

การดำเนินการแบบกลุ่มที่ถึงขีดจำกัด 5000 (ตัดทอนอย่างเงียบ ๆ):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc",
"removedUserIds": ["u_0001", "u_0002", "/* … exactly 5000 entries total */"]
}

การเห็นอาร์เรย์ที่มี 5000 รายการพอดีควรกระตุ้นการกระทบยอด GET /organizations/:id/users (หรือ /applications).

เหตุการณ์บทบาทองค์กร

type OrganizationRole = {
id: string;
name: string;
description?: string;
};
type OrganizationScope = {
id: string;
name: string;
description?: string;
};
EventFieldTypeOptionalNotes
OrganizationRole.CreateddataOrganizationRoleเอนทิตีบทบาทองค์กรที่สร้างขึ้น.
OrganizationRole.Data.UpdateddataOrganizationRoleเอนทิตีบทบาทองค์กรที่อัปเดต.
OrganizationRole.Deleteddatanull/
OrganizationRole.Scopes.Updateddatanull/
OrganizationRole.Scopes.UpdatedorganizationRoleIdstringID บทบาทที่ขอบเขตถูกกำหนดให้ (มีเฉพาะเมื่อเหตุการณ์ถูกกระตุ้นโดยการสร้างบทบาทที่มีขอบเขตที่กำหนดล่วงหน้า).

เหตุการณ์สิทธิ์องค์กร (scope)

EventFieldTypeOptionalNotes
OrganizationScope.CreateddataOrganizationScopeเอนทิตีขอบเขตองค์กรที่สร้างขึ้น.
OrganizationScope.Data.UpdateddataOrganizationScopeเอนทิตีขอบเขตองค์กรที่อัปเดต.
OrganizationScope.Deleteddatanull/

Payload ของเหตุการณ์ Exception

Events: Identifier.Lockout.

ถูกเรียกใช้เมื่อเกิดเหตุการณ์ด้านความปลอดภัย — เช่น บัญชีถูกล็อกหลังจากพยายามยืนยันตัวตนล้มเหลวติดต่อกัน เหตุการณ์เหล่านี้มักมาจากกระบวนการที่ผู้ใช้เผชิญหน้า ดังนั้นเนื้อหาจึงมี:

enum SignInIdentifier {
Email = 'email',
Phone = 'phone',
Username = 'username',
}
FieldTypeOptionalNotes
typeSignInIdentifierประเภทตัวระบุของผู้ใช้ เช่น อีเมล โทรศัพท์ หรือชื่อผู้ใช้.
valuestringค่าตัวระบุของผู้ใช้ที่กระตุ้นการล็อกเอาต์.