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

สร้างสคริปต์การอ้างสิทธิ์โทเค็นแบบกำหนดเอง

เพื่อ เพิ่มการอ้างสิทธิ์แบบกำหนดเอง ให้กับ โทเค็นการเข้าถึง (Access token) คุณต้องเตรียมสคริปต์ที่คืนอ็อบเจกต์ซึ่งมีการอ้างสิทธิ์เหล่านั้น สคริปต์ควรเขียนเป็นฟังก์ชัน JavaScript ที่คืนอ็อบเจกต์ซึ่งมีการอ้างสิทธิ์แบบกำหนดเอง

  1. ไปที่ Console > Custom JWT

  2. มีโทเค็นการเข้าถึงสองประเภทที่คุณสามารถปรับแต่งการอ้างสิทธิ์ของโทเค็นได้:

    • โทเค็นการเข้าถึงของผู้ใช้ (User access token): โทเค็นการเข้าถึงที่ออกให้กับผู้ใช้ปลายทาง เช่น สำหรับแอปพลิเคชันเว็บหรือแอปมือถือ
    • โทเค็นการเข้าถึงแบบเครื่องต่อเครื่อง (Machine-to-Machine access token): โทเค็นการเข้าถึงที่ออกให้กับบริการหรือแอปพลิเคชัน เช่น สำหรับ แอปพลิเคชันเครื่องต่อเครื่อง

    โทเค็นการเข้าถึงแต่ละประเภทอาจมีบริบท payload ของโทเค็นที่แตกต่างกัน คุณสามารถปรับแต่งการอ้างสิทธิ์ของโทเค็นแต่ละประเภทแยกกันได้

    เลือกประเภทโทเค็นการเข้าถึงที่คุณต้องการปรับแต่งการอ้างสิทธิ์ แล้วคลิกปุ่ม Add custom claims เพื่อสร้างสคริปต์ใหม่

บันทึก:

ฟีเจอร์การอ้างสิทธิ์โทเค็นแบบกำหนดเองนี้ใช้ได้เฉพาะกับ:

สร้างฟังก์ชัน getCustomJwtClaims()

ในหน้า Custom JWT รายละเอียด คุณจะพบตัวแก้ไขสคริปต์สำหรับเขียนสคริปต์การอ้างสิทธิ์โทเค็นแบบกำหนดเอง สคริปต์ควรเป็นฟังก์ชัน JavaScript ที่คืนอ็อบเจกต์ของการอ้างสิทธิ์แบบกำหนดเอง

หน้ารายละเอียดการอ้างสิทธิ์โทเค็นแบบกำหนดเอง

ขั้นตอนที่ 1: แก้ไขสคริปต์

ใช้ตัวแก้ไขโค้ดทางด้านซ้ายเพื่อปรับแต่งสคริปต์ มี getCustomJwtClaims ค่าเริ่มต้นที่คืนอ็อบเจกต์ว่างไว้ให้คุณเริ่มต้น คุณสามารถปรับแต่งฟังก์ชันนี้ให้คืนอ็อบเจกต์ของการอ้างสิทธิ์แบบกำหนดเองของคุณเองได้

const getCustomJwtClaims = async ({ token, context, environmentVariables }) => {
return {};
};

ตัวแก้ไขนี้ใช้ JavaScript language server เพื่อให้ไฮไลต์ไวยากรณ์พื้นฐาน การเติมโค้ดอัตโนมัติ และการตรวจสอบข้อผิดพลาด พารามิเตอร์อินพุตถูกกำหนดชนิดและมีเอกสารประกอบในรูปแบบ jsDoc คุณสามารถใช้ IntelliSense ของตัวแก้ไขเพื่อเข้าถึงพร็อพเพอร์ตี้ของอ็อบเจกต์อินพุตได้อย่างถูกต้อง คุณสามารถดูรายละเอียดนิยามพารามิเตอร์ได้ทางด้านขวาของหน้า

บันทึก:

ฟังก์ชันนี้จะถูกส่งออกเป็นโมดูล ตรวจสอบให้แน่ใจว่าชื่อฟังก์ชันยังคงเป็น getCustomJwtClaims เพื่อให้โมดูลสามารถส่งออกฟังก์ชันได้อย่างถูกต้อง

ขั้นตอนที่ 2: พารามิเตอร์อินพุต

ฟังก์ชัน getCustomJwtClaims รับอ็อบเจกต์เป็นพารามิเตอร์อินพุต อ็อบเจกต์อินพุตนี้มีพร็อพเพอร์ตี้ดังต่อไปนี้:

token

อ็อบเจกต์ payload ของโทเค็น อ็อบเจกต์นี้มีการอ้างสิทธิ์โทเค็นดั้งเดิมและเมตาดาต้าที่คุณอาจต้องเข้าถึงในสคริปต์

คุณสามารถดูนิยามชนิดของอ็อบเจกต์ payload ของโทเค็นและอ็อบเจกต์ข้อมูลผู้ใช้ได้ทางด้านขวาของหน้า IntelliSense ของตัวแก้ไขจะช่วยให้คุณเข้าถึงพร็อพเพอร์ตี้เหล่านี้ได้อย่างถูกต้อง

  • อ็อบเจกต์ข้อมูลโทเค็นการเข้าถึงของผู้ใช้
    พร็อพเพอร์ตี้คำอธิบายชนิดข้อมูล
    jtiรหัส JWT ที่ไม่ซ้ำกันstring
    audผู้รับ (Audience) ของโทเค็นstring
    scopeขอบเขต (Scopes) ของโทเค็นstring
    clientIdรหัสไคลเอนต์ของโทเค็นstring
    accountIdรหัสผู้ใช้ของโทเค็นstring
    expiresWithSessionโทเค็นจะหมดอายุตามเซสชันหรือไม่boolean
    grantIdรหัส grant การยืนยันตัวตนปัจจุบันของโทเค็นstring
    gtyประเภท grant ของโทเค็นstring
    kindประเภทของโทเค็นAccessToken
  • อ็อบเจกต์ข้อมูลโทเค็นการเข้าถึงแบบเครื่องต่อเครื่อง
    พร็อพเพอร์ตี้คำอธิบายชนิดข้อมูล
    jtiรหัส JWT ที่ไม่ซ้ำกันstring
    audผู้รับ (Audience) ของโทเค็นstring
    scopeขอบเขต (Scopes) ของโทเค็นstring
    clientIdรหัสไคลเอนต์ของโทเค็นstring
    kindประเภทของโทเค็นClientCredentials

context (ใช้ได้เฉพาะกับโทเค็นการเข้าถึงของผู้ใช้)

อ็อบเจกต์ context มีข้อมูลผู้ใช้และข้อมูล grant ที่เกี่ยวข้องกับกระบวนการการอนุญาต (Authorization) ปัจจุบัน

  • อ็อบเจกต์ข้อมูลผู้ใช้ สำหรับโทเค็นการเข้าถึงของผู้ใช้ Logto ให้ context ข้อมูลผู้ใช้เพิ่มเติมสำหรับการเข้าถึง อ็อบเจกต์ข้อมูลผู้ใช้นี้มีข้อมูลโปรไฟล์ผู้ใช้และข้อมูลสมาชิกองค์กรทั้งหมดที่คุณอาจต้องใช้ในการตั้งค่าการอ้างสิทธิ์แบบกำหนดเอง โปรดดู ผู้ใช้ และ องค์กร สำหรับรายละเอียดเพิ่มเติม

  • อ็อบเจกต์ข้อมูล grant สำหรับโทเค็นการเข้าถึงของผู้ใช้ที่ได้จากการแลกเปลี่ยนโทเค็นสวมรอย Logto ให้ context ข้อมูล grant เพิ่มเติมสำหรับการเข้าถึง อ็อบเจกต์ข้อมูล grant นี้มี context แบบกำหนดเองจาก subject token โปรดดู การสวมรอยผู้ใช้ สำหรับรายละเอียดเพิ่มเติม

  • อ็อบเจกต์ข้อมูลการโต้ตอบของผู้ใช้ สำหรับโทเค็นการเข้าถึงของผู้ใช้ อาจมีกรณีที่คุณต้องเข้าถึงรายละเอียดการโต้ตอบของผู้ใช้สำหรับเซสชันการอนุญาตปัจจุบัน เช่น คุณอาจต้องดึงข้อมูลตัวตน SSO สำหรับองค์กรที่ผู้ใช้ใช้ในการลงชื่อเข้าใช้ อ็อบเจกต์ข้อมูลการโต้ตอบของผู้ใช้นี้มีข้อมูลการโต้ตอบล่าสุดที่ผู้ใช้ส่งมา รวมถึง:

    พร็อพเพอร์ตี้คำอธิบายชนิดข้อมูล
    interactionEventเหตุการณ์การโต้ตอบของผู้ใช้ปัจจุบันSignIn หรือ Register
    userIdรหัสผู้ใช้ของการโต้ตอบปัจจุบันstring
    verificationRecordsรายการบันทึกการยืนยันตัวตนที่ผู้ใช้ส่งมาเพื่อระบุตัวตนและยืนยันตัวตนระหว่างการโต้ตอบ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

ทดสอบสคริปต์ JWT แบบกำหนดเอง
บันทึก:

ผลลัพธ์การทดสอบคือ output ของฟังก์ชัน getCustomJwtClaims ที่ใช้ mock data ที่คุณตั้งค่า ("extra token claims" ที่ได้หลังจากจบขั้นตอนที่ 3 ใน sequence diagram) ข้อมูล payload ของโทเค็นจริงและ context ข้อมูลผู้ใช้จะต่างออกไปเมื่อสคริปต์ถูกรันในกระบวนการออกโทเค็นจริง

คลิกปุ่ม Create เพื่อบันทึกสคริปต์ สคริปต์การอ้างสิทธิ์โทเค็นแบบกำหนดเองจะถูกบันทึกและนำไปใช้กับกระบวนการออกโทเค็นการเข้าถึง