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

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

เพื่อ เพิ่มการอ้างสิทธิ์ (Claims) แบบกำหนดเอง ให้กับ โทเค็นการเข้าถึง (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 ของตัวแก้ไขจะช่วยให้คุณเข้าถึงพร็อพเพอร์ตี้เหล่านี้ได้อย่างถูกต้อง

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

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

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

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

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

    PropertyคำอธิบายType
    idรหัสองค์กรที่ไม่ซ้ำกันstring
    nameชื่อองค์กรstring
    descriptionคำอธิบายองค์กรstring | null
    customDataข้อมูล custom ขององค์กรRecord<string, unknown>

    โปรดดู องค์กร สำหรับรายละเอียดเพิ่มเติม

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

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

    PropertyคำอธิบายType
    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() ช่วยให้คุณปฏิเสธกระบวนการออกโทเค็นพร้อมข้อความกำหนดเอง คุณสามารถใช้ฟังก์ชันนี้เพื่อบังคับตรวจสอบสิทธิ์เพิ่มเติมในกระบวนการออกโทเค็น

Runtime APIs

สคริปต์โทเค็นการเข้าถึงแบบกำหนดเองสามารถใช้ Web APIs มาตรฐานเหล่านี้ได้ทั้งใน Logto Cloud และ Logto ที่โฮสต์เอง:

  • fetch, Request, Response, และ Headers
  • Web Crypto ผ่าน crypto และ crypto.subtle
  • TextEncoder และ TextDecoder
  • URL และ URLSearchParams

ตัวอย่างเช่น คุณสามารถคำนวณค่า SHA-256 และ HMAC-SHA-256 ด้วย Web Crypto:

const toHex = (buffer) =>
[...new Uint8Array(buffer)].map((byte) => byte.toString(16).padStart(2, '0')).join('');

const sha256 = async (input) =>
toHex(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input)));

const hmacSha256 = async (key, input) => {
const encoder = new TextEncoder();
const cryptoKey = await crypto.subtle.importKey(
'raw',
encoder.encode(key),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign']
);

return toHex(await crypto.subtle.sign('HMAC', cryptoKey, encoder.encode(input)));
};

สคริปต์ไม่สามารถ import แพ็กเกจได้ หลีกเลี่ยงการใช้ global และโมดูลเฉพาะ Node.js เพราะไม่สามารถใช้งานร่วมกันระหว่าง Logto ที่โฮสต์เองกับ Logto Cloud และไม่อยู่ในข้อตกลงการรองรับของสคริปต์

ขั้นตอนที่ 3: ดึงข้อมูลภายนอก

คุณสามารถใช้ฟังก์ชัน fetch มาตรฐานเพื่อดึงข้อมูลภายนอกในสคริปต์ของคุณ ฟังก์ชัน 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 การอนุญาต (authorization) ที่เหมาะสมเพื่อปกป้อง API ภายนอกของคุณจากการเข้าถึงโดยไม่ได้รับอนุญาต

ขั้นตอนที่ 4: ทดสอบสคริปต์

อย่าลืมทดสอบสคริปต์ของคุณก่อนบันทึก คลิกที่แท็บ Test context ทางขวาของหน้าเพื่อปรับแต่ง mock token payload และ context ข้อมูลผู้ใช้สำหรับการทดสอบ

คลิก Run test ที่มุมขวาบนของตัวแก้ไขเพื่อรันสคริปต์ด้วย mock data ผลลัพธ์ของสคริปต์จะแสดงใน drawer Test Result

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

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

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