สร้างสคริปต์โทเค็นการเข้าถึงแบบกำหนดเอง (Create a custom access token script)
เพื่อเพิ่มการอ้างสิทธิ์ (Claims) แบบกำหนดเอง ให้กับ โทเค็นการเข้าถึง (Access token) คุณจำเป็นต้องจัดเตรียมสคริปต์ที่คืนค่าอ็อบเจกต์ซึ่งมีการอ้างสิทธิ์เหล่านั้น สคริปต์ควรเขียนเป็นฟังก์ชัน JavaScript ที่คืนค่าอ็อบเจกต์ซึ่งมีการอ้างสิทธิ์แบบกำหนดเอง
-
ไปที่ Console > Custom JWT
-
มีโทเค็นการเข้าถึงสองประเภทที่คุณสามารถปรับแต่งการอ้างสิทธิ์ของโทเค็นได้:
- โทเค็นการเข้าถึงของผู้ใช้ (User access token): โทเค็นการเข้าถึงที่ออกให้กับผู้ใช้ปลายทาง เช่น สำหรับแอปพลิเคชันเว็บหรือแอปมือถือ
- โทเค็นการเข้าถึงแบบเครื่องต่อเครื่อง (Machine-to-Machine access token): โทเค็นการเข้าถึงที่ออกให้กับบริการหรือแอปพลิเคชัน เช่น สำหรับ แอปพลิเคชันเครื่องต่อเครื่อง
โทเค็นการเข้าถึงแต่ละประเภทอาจมีบริบท payload ที่แตกต่างกัน คุณสามารถปรับแต่งการอ้างสิทธิ์ของโทเค็นแต่ละประเภทแยกกันได้
เลือกประเภทโทเค็นการเข้าถึงที่คุณต้องการปรับแต่งการอ้างสิทธิ์ แล้วคลิกปุ่ม Add custom claims เพื่อสร้างสคริปต์ใหม่
ฟีเจอร์การอ้างสิทธิ์โทเค็นแบบกำหนดเองนี้ใช้ได้เฉพาะกับ:
- ผู้ใช้ Logto OSS
- ผู้เช่า Logto Cloud ที่มีสภาพแวดล้อมการพัฒนา
- ผู้เช่า Logto Cloud แบบชำระเงินที่มีสภาพแวดล้อม production (รวมถึง Pro tenants และ Enterprise tenants)
สร้างฟังก์ชัน getCustomJwtClaims()
ในหน้ารายละเอียด Custom JWT คุณจะพบตัวแก้ไขสคริปต์สำหรับเขียนสคริปต์การอ้างสิทธิ์โทเค็นแบบกำหนดเอง สคริปต์ควรเป็นฟังก์ชัน JavaScript ที่คืนค่าอ็อบเจกต์ของการอ้างสิทธิ์แบบกำหนดเอง
ขั้นตอนที่ 1: แก้ไขสคริปต์
ใช้ตัวแก้ไขโค้ดทางด้านซ้ายเพื่อแก้ไขสคริปต์ โดยมี getCustomJwtClaims เริ่มต้นที่คืนค่าอ็อบเจกต์ว่างไว้ให้คุณเริ่มต้น คุณสามารถแก้ไขฟังก์ชันนี้เพื่อคืนค่าอ็อบเจกต์ของการอ้างสิทธิ์แบบกำหนดเองของคุณเอง
const getCustomJwtClaims = async ({ token, context, environmentVariables }) => {
return {};
};
ตัวแก้ไขนี้ใช้ language server ของ JavaScript เพื่อให้การเน้นไวยากรณ์ การเติมโค้ดอัตโนมัติ และการตรวจสอบข้อผิดพลาด พารามิเตอร์อินพุตถูกกำหนดชนิดและมีเอกสารประกอบในรูปแบบ jsDoc คุณสามารถใช้ IntelliSense ของตัวแก้ไขเพื่อเข้าถึงพร็อพเพอร์ตี้ของอ็อบเจกต์อินพุตได้อย่างถูกต้อง คุณสามารถดูรายละเอียดการกำหนดพารามิเตอร์ได้ทางด้านขวาของหน้า
ฟังก์ชันนี้จะถูก export เป็นโมดูล ตรวจสอบให้แน่ใจว่าชื่อฟังก์ชันยังคงเป็น getCustomJwtClaims เพื่อให้โมดูลสามารถ export ฟังก์ชันได้อย่างถูกต้อง
ขั้นตอนที่ 2: พารามิเตอร์อินพุต
ฟังก์ชัน getCustomJwtClaims รับอ็อบเจกต์เป็นพารามิเตอร์อินพุต อ็อบเจกต์อินพุตนี้มีพร็อพเพอร์ตี้ดังต่อไปนี้:
token
อ็อบเจกต์ payload ของโทเค็น อ็อบเจกต์นี้มีการอ้างสิทธิ์โทเค็นดั้งเดิมและเมตาดาต้าที่คุณอาจต้องเข้าถึงในสคริปต์
คุณสามารถดูรายละเอียดชนิดของอ็อบเจกต์ payload ของโทเค็นและอ็อบเจกต์ข้อมูลผู้ใช้ได้ทางด้านขวาของหน้า IntelliSense ของตัวแก้ไขจะช่วยให้คุณเข้าถึงพร็อพเพอร์ตี้เหล่านี้ได้อย่างถูกต้อง
- อ็อบเจกต์ข้อมูลโทเค็นการเข้าถึงของผู้ใช้
Property Description Type jtiรหัส JWT ที่ไม่ซ้ำ stringaudผู้รับของโทเค็น stringscopeขอบเขตของโทเค็น stringclientIdรหัส client ของโทเค็น stringaccountIdรหัสผู้ใช้ของโทเค็น stringexpiresWithSessionโทเค็นจะหมดอายุตาม session หรือไม่ booleangrantIdรหัส grant การยืนยันตัวตนปัจจุบันของโทเค็น stringgtyประเภท grant ของโทเค็น stringkindประเภทของโทเค็น AccessToken - อ็อบเจกต์ข้อมูลโทเค็นการเข้าถึงแบบเครื่องต่อเครื่อง
Property Description Type jtiรหัส JWT ที่ไม่ซ้ำ stringaudผู้รับของโทเค็น stringscopeขอบเขตของโทเค็น stringclientIdรหัส client ของโทเค็น stringkindประเภทของโทเค็น ClientCredentials
context (ใช้ได้เฉพาะกับโทเค็นการเข้าถึงของผู้ใช้)
อ็อบเจกต์ context มีข้อมูลผู้ใช้และข้อมูล grant ที่เกี่ยวข้องกับกระบวนการการอนุญาต (Authorization) ปัจจุบัน
-
อ็อบเจกต์ข้อมูลผู้ใช้ สำหรับโทเค็นการเข้าถึงของผู้ใช้ Logto จะให้ context ข้อมูลผู้ใช้เพิ่มเติมสำหรับการเข้าถึง อ็อบเจกต์ข้อมูลผู้ใช้นี้มีข้อมูลโปรไฟล์ผู้ใช้และข้อมูลสมาชิกองค์กรที่คุณอาจต้องใช้ในการตั้งค่าการอ้างสิทธิ์แบบกำหนดเอง โปรดดู ผู้ใช้ และ องค์กร สำหรับรายละเอียดเพิ่มเติม
-
อ็อบเจกต์ข้อมูล grant สำหรับโทเค็นการเข้าถึงของผู้ใช้ที่ได้จากการแลกเปลี่ยนโทเค็นสวมรอย (impersonation token exchange) Logto จะให้ context ข้อมูล grant เพิ่มเติม อ็อบเจกต์ข้อมูล grant นี้มี context แบบกำหนดเองจาก subject token โปรดดู การสวมรอยผู้ใช้ (Impersonation) สำหรับรายละเอียดเพิ่มเติม
-
อ็อบเจกต์ข้อมูลการโต้ตอบของผู้ใช้ สำหรับโทเค็นการเข้าถึงของผู้ใช้ อาจมีกรณีที่คุณต้องเข้าถึงรายละเอียดการโต้ตอบของผู้ใช้สำหรับ session การอนุญาต (Authorization) ปัจจุบัน เช่น คุณอาจต้องดึงข้อมูล enterprise SSO identity ที่ผู้ใช้ใช้ในการลงชื่อเข้าใช้ อ็อบเจกต์ข้อมูลการโต้ตอบของผู้ใช้นี้มีข้อมูลการโต้ตอบล่าสุดที่ผู้ใช้ส่งมา รวมถึง:
Property Description Type interactionEventเหตุการณ์การโต้ตอบของผู้ใช้ปัจจุบัน SignInหรือRegisteruserIdรหัสผู้ใช้ของการโต้ตอบปัจจุบัน stringverificationRecordsรายการบันทึกการยืนยันตัวตนที่ผู้ใช้ส่งมาเพื่อระบุตัวตนและยืนยันตัวตนระหว่างการโต้ตอบ VerificationRecord[]ประเภทของบันทึกการยืนยันตัวตน:
// VerificationType.Password
{
id: string;
type: 'Password';
identifier: {
type: 'username' | 'email' | 'phone' | 'userId';
value: string;
}
verified: boolean;
}// VerificationType.EmailVerificationCode
{
id: string;
templateType: 'SignIn' | 'Register' | 'ForgotPassword' | 'Generic';
verified: boolean;
type: 'EmailVerificationCode';
identifier: {
type: 'email';
value: string;
}
}// VerificationType.PhoneVerificationCode
{
id: string;
templateType: 'SignIn' | 'Register' | 'ForgotPassword' | 'Generic';
verified: boolean;
type: 'PhoneVerificationCode';
identifier: {
type: 'phone';
value: string;
}
}// VerificationType.Social
{
id: string;
type: 'Social';
connectorId: string;
socialUserInfo?: {
id: string;
email?: string | undefined;
phone?: string | undefined;
name?: string | undefined;
avatar?: string | undefined;
rawData?: Record<string, unknown> | undefined;
} | undefined;
}// VerificationType.EnterpriseSso
{
id: string;
type: 'EnterpriseSso';
connectorId: string;
enterpriseUserInfo?: {
id: string;
email?: string | undefined;
phone?: string | undefined;
name?: string | undefined;
avatar?: string | undefined;
[key: string]?: unknown;
} | undefined;
issuer?: string | undefined;
}// VerificationType.Totp (MFA)
{
id: string;
type: 'Totp';
userId: string;
verified: boolean;
}// VerificationType.WebAuthn (MFA)
{
id: string;
type: 'WebAuthn';
userId: string;
verified: boolean;
}// VerificationType.BackupCode (MFA)
{
id: string;
type: "BackupCode";
userId: string;
code?: string | undefined;
}// VerificationType.OneTimeToken
{
id: string;
type: "OneTimeToken";
verified: boolean;
identifier: {
type: "email";
value: string;
};
oneTimeTokenContext?: {
jitOrganizationIds?: string[] | undefined;
} | undefined;
}บันทึก:อาจมีบันทึกการยืนยันตัวตนหลายรายการในอ็อบเจกต์ข้อมูลการโต้ตอบของผู้ใช้ โดยเฉพาะเมื่อผู้ใช้ผ่านกระบวนการลงชื่อเข้าใช้หรือสมัครสมาชิกหลายครั้ง
เช่น ผู้ใช้ลงชื่อเข้าใช้ด้วยบันทึก
Socialแล้วผูกอีเมลใหม่ผ่านบันทึกEmailVerificationCodeและยืนยันสถานะ MFA ด้วยบันทึกTotpในกรณีนี้ คุณอาจต้องจัดการบันทึกการยืนยันตัวตนทั้งหมดในสคริปต์ของคุณแต่ละประเภทของบันทึกการยืนยันตัวตนจะมีเพียงหนึ่งรายการในอ็อบเจกต์ข้อมูลการโต้ตอบของผู้ใช้
environmentVariables
ใช้ส่วน Set environment variables ทางด้านขวาเพื่อกำหนด environment variables สำหรับสคริปต์ของคุณ คุณสามารถใช้ตัวแปรเหล่านี้เพื่อเก็บข้อมูลสำคัญหรือข้อมูลการตั้งค่าที่คุณไม่ต้องการเขียนลงในสคริปต์โดยตรง เช่น API key, secret หรือ URL
ตัวแปร environment variables ทั้งหมดที่คุณตั้งค่าที่นี่จะสามารถใช้งานได้ในสคริปต์ ใช้อ็อบเจกต์ environmentVariables ในพารามิเตอร์อินพุตเพื่อเข้าถึงตัวแปรเหล่านี้
api
อ็อบเจกต์ api มีฟังก์ชันอรรถประโยชน์ที่คุณสามารถใช้ในสคริปต์เพื่อควบคุมการออกโทเค็นเพิ่มเติม อ็อบเจกต์ api มีฟังก์ชันดังนี้:
api.denyAccess(message?: string): void
ฟังก์ชัน api.denyAccess() ช่วยให้คุณปฏิเสธกระบวนการออกโทเค็นพร้อมข้อความกำหนดเอง คุณสามารถใช้ฟังก์ชันนี้เพื่อบังคับตรวจสอบสิทธิ์เพิ่มเติมในกระบวนการออกโทเค็น
ขั้นตอนที่ 3: ดึงข้อมูลภายนอก
คุณสามารถใช้ฟังก์ชัน fetch ที่มีใน node เพื่อดึงข้อมูลภายนอกในสคริปต์ของคุณ ฟังก์ชัน fetch เป็นฟังก์ชันแบบ promise ที่ช่วยให้คุณส่ง HTTP request ไปยัง API ภายนอกได้
const getCustomJwtClaims = async ({ environmentVariables }) => {
const response = await fetch('https://api.example.com/data', {
headers: {
Authorization: `Bearer ${environmentVariables.API_KEY}`,
},
});
const data = await response.json();
return {
data,
};
};
โปรดทราบ การดึงข้อมูลภายนอกอาจทำให้กระบวนการออกโทเค็นล่าช้า ตรวจสอบให้แน่ใจว่า API ภายนอกมีความน่าเชื่อถือและรวดเร็วเพียงพอต่อความต้องการของคุณ
นอกจากนี้:
- จัดการข้อผิดพลาดและ timeout ในสคริปต์ของคุณอย่างเหมาะสมเพื่อป้องกันไม่ให้กระบวนการออกโทเค็นถูกบล็อก
- ใช้ header การอนุญาตที่เหมาะสมเพื่อปกป้อง API ภายนอกของคุณจากการเข้าถึงโดยไม่ได้รับอนุญาต
ขั้นตอนที่ 4: ทดสอบสคริปต์
อย่าลืมทดสอบสคริปต์ของคุณก่อนบันทึก คลิกที่แท็บ Test context ทางด้านขวาของหน้าเพื่อแก้ไข mock token payload และ context ข้อมูลผู้ใช้สำหรับการทดสอบ
คลิก Run test ที่มุมขวาบนของตัวแก้ไขเพื่อรันสคริปต์ด้วย mock data ผลลัพธ์ของสคริปต์จะแสดงใน Test Result drawer
ผลลัพธ์การทดสอบคือ output ของฟังก์ชัน getCustomJwtClaims กับ mock data ที่คุณตั้งค่า (“extra token claims” ที่ได้หลังจากขั้นตอนที่ 3 ใน sequence diagram) ข้อมูล payload ของโทเค็นจริงและ context ข้อมูลผู้ใช้จะต่างออกไปเมื่อสคริปต์ถูกรันในกระบวนการออกโทเค็นจริง
คลิกปุ่ม Create เพื่อบันทึกสคริปต์ สคริปต์การอ้างสิทธิ์โทเค็นแบบกำหนดเองจะถูกบันทึกและนำไปใช้กับกระบวนการออกโทเค็นการเข้าถึง