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

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

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

  1. ไปที่ Console > Custom JWT

  2. มีโทเค็นการเข้าถึง 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 {};
};

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

บันทึก:

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

สำหรับ user access tokens การอ้างสิทธิ์ context การยืนยันตัวตน acr, amr, และ auth_time เป็น reserved โดย Logto (ดู Step-up authentication) หากสคริปต์ของคุณคืน key เหล่านี้ Logto จะเพิกเฉยและใช้ context การยืนยันตัวตนที่ได้มาแทน

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

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

token​

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

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

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

context (ใช้ได้เฉพาะกับ user access token)​

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

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

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

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

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

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

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

    PropertyคำอธิบายType
    interactionEventเหตุการณ์การโต้ตอบของผู้ใช้ปัจจุบันSignIn or Register
    userIduser id ของการโต้ตอบผู้ใช้ปัจจุบันstring
    verificationRecordsรายการ verification record ที่ผู้ใช้ส่งมาเพื่อยืนยันตัวตนระหว่างการโต้ตอบVerificationRecord[]

    ประเภท verification record:

    // 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;
    }
    บันทึก:

    อาจมี verification record หลายรายการในอ็อบเจกต์ข้อมูลการโต้ตอบของผู้ใช้ โดยเฉพาะเมื่อผู้ใช้ผ่านกระบวนการลงชื่อเข้าใช้หรือสมัครสมาชิกหลายครั้ง

    เช่น ผู้ใช้ลงชื่อเข้าใช้ด้วย verification record แบบ Social จากนั้นผูกอีเมลใหม่ผ่าน verification record แบบ EmailVerificationCode และยืนยันสถานะ MFA ด้วย verification record แบบ Totp ในกรณีนี้ คุณอาจต้องจัดการ verification record ทั้งหมดในสคริปต์ของคุณ

    verification record แต่ละประเภทจะมีเพียงหนึ่งรายการในอ็อบเจกต์ข้อมูลการโต้ตอบของผู้ใช้

environmentVariables​

ใช้ส่วน Set environment variables ทางขวาเพื่อกำหนด environment variables สำหรับสคริปต์ของคุณ คุณสามารถใช้ตัวแปรเหล่านี้เพื่อเก็บข้อมูลสำคัญหรือค่าคอนฟิกที่ไม่ต้องการ hardcode ในสคริปต์ เช่น 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 ภายนอกมีความเสถียรและรวดเร็วเพียงพอต่อความต้องการของคุณ

นอกจากนี้:

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