สร้างสคริปต์โทเค็นการเข้าถึงแบบกำหนดเอง
เพื่อ เพิ่มการอ้างสิทธิ์ (claims) แบบกำหนดเอง ให้กับ โทเค็นการเข้าถึง (Access token) คุณต้องเตรียมสคริปต์ที่คืนอ็อบเจกต์ซึ่งมีการอ้างสิทธิ์เหล่านั้น สคริปต์ควรเขียนเป็นฟังก์ชัน JavaScript ที่คืนอ็อบเจกต์พร้อมการอ้างสิทธิ์แบบกำหนดเอง
-
ไปที่ Console > Custom JWT
-
มีโทเค็นการเข้าถึง 2 ประเภทที่คุณสามารถปรับแต่งการอ้างสิทธิ์ได้:
- โทเค็นการเข้าถึงของผู้ใช้ (User access token): โทเค็นการเข้าถึงที่ออกให้กับผู้ใช้ปลายทาง เช่น สำหรับเว็บแอปพลิเคชันหรือแอปมือถือ
- โทเค็นการเข้าถึงแบบเครื่องต่อเครื่อง (Machine-to-Machine access token): โทเค็นการเข้าถึงที่ออกให้กับบริการหรือแอปพลิเคชัน เช่น สำหรับ แอปพลิเคชันเครื่องต่อเครื่อง
โทเค็นการเข้าถึงแต่ละประเภทอาจมีโครงสร้าง payload ที่แตกต่างกัน คุณสามารถปรับแต่งการอ้างสิทธิ์ของแต่ละประเภทแยกกันได้
เลือกประเภทโทเค็นการเข้าถึงที่ต้องการปรับแต่งการอ้างสิทธิ์ แล้วคลิกปุ่ม Add custom claims เพื่อสร้างสคริปต์ใหม่
ฟีเจอร์การอ้างสิทธิ์โทเค็นแบบกำหนดเองนี้ใช้ได้เฉพาะกับ:
- ผู้ใช้ Logto OSS
- Logto Cloud tenants ที่มีสภาพแวดล้อม development
- Logto Cloud paid tenants ที่มีสภาพแวดล้อม production (รวมถึง Pro tenants และ Enterprise tenants)
สร้างฟังก์ชัน 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 ที่ไม่ซ้ำ stringaudผู้รับ (Audience) ของโทเค็น stringscopeขอบเขต (Scopes) ของโทเค็น stringclientIdclient id ของโทเค็น stringaccountIduser id ของโทเค็น stringexpiresWithSessionโทเค็นจะหมดอายุตาม session หรือไม่ booleangrantIdgrant id ของการยืนยันตัวตนปัจจุบัน stringgtyประเภท grant ของโทเค็น stringkindประเภทโทเค็น AccessToken - อ็อบเจกต์ข้อมูลโทเค็นการเข้าถึงแบบเครื่องต่อเครื่อง
Property คำอธิบาย Type jtiรหัส JWT ที่ไม่ซ้ำ stringaudผู้รับ (Audience) ของโทเค็น stringscopeขอบเขต (Scopes) ของโทเค็น stringclientIdclient id ของโทเค็น stringkindประเภทโทเค็น 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รหัสองค์กรที่ไม่ซ้ำ stringnameชื่อองค์กร stringdescriptionคำอธิบายองค์กร string | nullcustomDataข้อมูล 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เหตุการณ์การโต้ตอบของผู้ใช้ปัจจุบัน SignInorRegisteruserIduser id ของการโต้ตอบผู้ใช้ปัจจุบัน stringverificationRecordsรายการ 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และTextDecoderURLและ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
ผลลัพธ์การทดสอบคือ output ของฟังก์ชัน getCustomJwtClaims กับ mock data ที่คุณตั้งค่า ("extra token claims" ที่ได้หลังจากขั้นตอนที่ 3 ใน sequence diagram) ข้อมูล payload และ context จริงจะต่างออกไปเมื่อสคริปต์ถูกรันในกระบวนการออกโทเค็น
คลิกปุ่ม Create เพื่อบันทึกสคริปต์ สคริปต์การอ้างสิทธิ์โทเค็นแบบกำหนดเองจะถูกบันทึกและนำไปใช้กับกระบวนการออกโทเค็นการเข้าถึง