เครื่องต่อเครื่อง: การยืนยันตัวตนกับ Logto
คู่มือนี้ถือว่าคุณได้สร้างแอปพลิเคชันประเภท "Machine-to-machine" ใน Admin Console แล้ว
แนะนำ
เครื่องต่อเครื่อง (Machine-to-machine; M2M) เป็นแนวปฏิบัติทั่วไปสำหรับการยืนยันตัวตนหากคุณมีแอป (ไม่ใช่ผู้ใช้) ที่ต้องสื่อสารกับทรัพยากรโดยตรง (โดยปกติแล้วแอป M2M ไม่ต้องมีการโต้ตอบกับผู้ใช้ จึงไม่มี UI) เช่น บริการ API ที่อัปเดตข้อมูลผู้ใช้แบบกำหนดเองใน Logto, บริการสถิติที่ดึงคำสั่งซื้อรายวัน ฯลฯ
เนื่องจาก Logto ใช้ RBAC เป็นนโยบายควบคุมการเข้าถึง การกำหนดบทบาท M2M ให้กับแอป M2M จึงเป็นสิ่งจำเป็นเพื่อปกป้อง API ของคุณที่ต้องการการสื่อสารโดยตรงระหว่างบริการ
เพื่อเรียนรู้เกี่ยวกับ RBAC ปัจจุบันของเราและความแตกต่างระหว่างบทบาทผู้ใช้กับบทบาท M2M ดูที่ กำหนดค่าบทบาทระดับโกลบอล เพื่อศึกษารายละเอียดเพิ่มเติม
มีกรณีการใช้งานหลัก 2 แบบของแอปเครื่องต่อเครื่องใน Logto:
- เข้าถึง Logto Management API: ในกรณีนี้ คุณต้องกำหนดบทบาท M2M ที่มีสิทธิ์
all
จาก Logto Management API ที่มีมาให้กับแอป M2M ของคุณ - เข้าถึงทรัพยากร API ของคุณ: ในกรณีนี้ คุณต้องกำหนดบทบาท M2M ที่มีสิทธิ์จากทรัพยากร API ของคุณให้กับแอป M2M
ระหว่างกระบวนการสร้างแอป M2M คุณจะถูกนำไปยังหน้าที่คุณสามารถกำหนด บทบาท M2M ให้กับแอปพลิเคชันของคุณได้:

หรือคุณยังสามารถกำหนดบทบาทเหล่านี้ได้ที่หน้ารายละเอียดแอป M2M เมื่อคุณได้สร้างแอป M2M ไว้แล้ว:

ต่อไป เราจะพาคุณผ่านกระบวนการแบบ end-to-end เพื่อความชัดเจน เราจะแยกขั้นตอนสำหรับการเข้าถึง Logto Management API และทรัพยากร API อื่น ๆ และสมมติว่าคุณได้สร้างแอป M2M ใน Logto แล้ว
ดึงโทเค็นการเข้าถึง (Fetch an access token)
พื้นฐานเกี่ยวกับคำขอโทเค็นการเข้าถึง
แอป M2M จะส่งคำขอ POST
ไปยัง token endpoint เพื่อดึงโทเค็นการเข้าถึง (Access token) โดยเพิ่มพารามิเตอร์ต่อไปนี้ในรูปแบบ application/x-www-form-urlencoded
ใน entity-body ของ HTTP request:
- grant_type: ต้องตั้งค่าเป็น
client_credentials
- resource: ทรัพยากรที่คุณต้องการเข้าถึง
- scope: ขอบเขตของคำขอการเข้าถึง
และคุณยังต้องแนบข้อมูลรับรองของแอป M2M ของคุณใน request header เพื่อให้ token endpoint ทำการยืนยันตัวตนแอป M2M ของคุณ
สิ่งนี้ทำได้โดยการแนบข้อมูลรับรองของแอปในรูปแบบ Basic authentication ใน request Authorization
header โดยที่ username คือ App ID และ password คือ App Secret
คุณสามารถค้นหา App ID และ App Secret ได้จากหน้ารายละเอียดของแอป M2M ของคุณ:

ตัวอย่างคำขอโทเค็นการเข้าถึง:
POST /oidc/token HTTP/1.1
Host: your.logto.endpoint
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&resource=https://shopping.api
&scope=read:products write:products
ขอรับโทเค็นการเข้าถึง
ในการสาธิตต่อไปนี้ ให้แทนที่ https://your.logto.endpoint
ด้วย Logto endpoint ที่คุณต้องการใช้งาน สำหรับ Logto Cloud จะเป็น https://{your-tenant-id}.logto.app
- สำหรับ Logto Management API
- สำหรับทรัพยากร API ของคุณ
Logto มี “Logto Management API” เป็นทรัพยากรในตัว ซึ่งเป็นทรัพยากรแบบอ่านอย่างเดียว (readonly) พร้อมสิทธิ์ all
เพื่อเข้าถึง Logto Management API คุณสามารถดูได้จากรายการทรัพยากร API ของคุณ
ตัวบ่งชี้ API ของทรัพยากรนี้จะอยู่ในรูปแบบ https://{your-tenant-id}.logto.app/api
และนี่จะเป็นค่าทรัพยากรที่ใช้ใน body ของคำขอโทเค็นการเข้าถึง (Access token)

ก่อนเข้าถึง Logto Management API ให้แน่ใจว่าแอป M2M ของคุณได้รับมอบหมายบทบาท M2M ที่มีสิทธิ์ all
จากทรัพยากร “Logto Management API” ที่มีอยู่ในระบบนี้แล้ว
Logto ยังมีบทบาท M2M ที่ตั้งค่าล่วงหน้าไว้ชื่อ “Logto Management API access” สำหรับ tenant ที่สร้างใหม่ ซึ่งได้มอบหมายสิทธิ์ all ของทรัพยากร Logto Management API ไว้แล้ว คุณสามารถใช้งานได้ทันทีโดยไม่ต้องตั้งค่าสิทธิ์เอง บทบาทที่ตั้งค่าล่วงหน้านี้สามารถแก้ไขหรือลบได้ตามต้องการ
ตอนนี้ รวบรวมทุกอย่างที่เรามีและส่งคำขอ:
- Node.js
- cURL
const logtoEndpoint = 'https://your.logto.endpoint'; // แทนที่ด้วย Logto endpoint ของคุณ
const tokenEndpoint = `${logtoEndpoint}/oidc/token`;
const applicationId = 'your-application-id';
const applicationSecret = 'your-application-secret';
const tenantId = 'your-tenant-id';
const fetchAccessToken = async () => {
return await fetch(tokenEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${Buffer.from(`${applicationId}:${applicationSecret}`).toString(
'base64'
)}`,
},
body: new URLSearchParams({
grant_type: 'client_credentials',
resource: `https://${tenantId}.logto.app/api`,
scope: 'all',
}).toString(),
});
};
curl --location \
--request POST 'https://your.logto.endpoint' \
--header 'Authorization: Basic ${your_auth_string}' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'resource=https://${tenantId}.logto.app/api' \
--data-urlencode 'scope=all'
อย่าลืมแทนค่าตัวอย่างด้วยค่าจริงของคุณเอง
สำหรับผู้ใช้ Logto Cloud: เมื่อคุณโต้ตอบกับ Logto Management API คุณไม่สามารถใช้โดเมนที่กำหนดเองได้ ให้ใช้ Logto endpoint เริ่มต้น https://{your_tenant_id}.logto.app/oidc/token
เพื่อขอรับโทเค็นการเข้าถึง
ในรายการ API Resource ของคุณ ให้ค้นหา API identifier ที่แอปต้องเข้าถึง หากคุณยังไม่ได้เพิ่ม API Resource ใน Logto หรือไม่ทราบว่า API Resource คืออะไร ดูที่ การอนุญาต (Authorization)

สมมติว่าเรามีสิทธิ์ read:products
และ write:products
อยู่ภายใต้ทรัพยากร API “Online Shopping” นี้
ก่อนเข้าถึงทรัพยากร API ของคุณ ตรวจสอบให้แน่ใจว่าแอป M2M ของคุณได้รับมอบหมายบทบาท M2M ที่มีสิทธิ์จากทรัพยากร API ของคุณแล้ว
ตอนนี้ รวบรวมทุกอย่างที่เรามีและส่งคำขอ:
- Node.js
- cURL
const logtoEndpoint = 'https://your.logto.endpoint';
const tokenEndpoint = `${logtoEndpoint}/oidc/token`;
const applicationId = 'your-application-id';
const applicationSecret = 'your-application-secret';
const fetchAccessToken = async () => {
return await fetch(tokenEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${Buffer.from(`${applicationId}:${applicationSecret}`).toString(
'base64'
)}`,
},
body: new URLSearchParams({
grant_type: 'client_credentials',
resource: 'https://shopping.api',
scope: 'read:products write:products',
}).toString(),
});
};
curl --location \
--request POST 'https://your.logto.endpoint/oidc/token' \
--header 'Authorization: Basic ${your_auth_string}' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'resource=https://shopping.api' \
--data-urlencode 'scope=read:products write:products'
การตอบกลับโทเค็นการเข้าถึง
ตัวอย่าง response ที่สำเร็จจะมีลักษณะดังนี้:
{
"access_token": "eyJhbG...2g", // ใช้โทเค็นนี้สำหรับเข้าถึง Logto Management API
"expires_in": 3600, // อายุโทเค็นเป็นวินาที
"token_type": "Bearer", // ประเภทการยืนยันตัวตนสำหรับคำขอเมื่อใช้โทเค็นการเข้าถึง
"scope": "all" // scope `all` สำหรับ Logto Management API
}
ขณะนี้ Logto ยังไม่รองรับการใช้แอป M2M เพื่อแทนผู้ใช้ sub
ใน payload ของโทเค็นการเข้าถึง (access token) จะเป็น App ID
เข้าถึงทรัพยากรโดยใช้โทเค็นการเข้าถึง
คุณอาจสังเกตเห็นว่าการตอบกลับโทเค็นมีฟิลด์ token_type
ซึ่งถูกกำหนดไว้เป็น Bearer
เสมอ
ดังนั้น คุณควรใส่โทเค็นการเข้าถึง (Access token) ลงในฟิลด์ Authorization
ของ HTTP headers โดยใช้รูปแบบ Bearer (Bearer YOUR_TOKEN
) เมื่อคุณโต้ตอบกับเซิร์ฟเวอร์ทรัพยากร API ของคุณ
- โต้ตอบกับ Logto Management API
- โต้ตอบกับทรัพยากร API ของคุณ
การใช้โทเค็นการเข้าถึง (Access token) ที่ร้องขอ กับทรัพยากร Management API ที่มีอยู่ใน Logto https://[your-tenant-id].logto.app/api
เพื่อดึงข้อมูลแอปพลิเคชันทั้งหมดใน Logto:
- Node.js
- cURL
const logtoEndpoint = 'https://your.logto.endpoint'; // แทนที่ด้วย Logto endpoint ของคุณ
const accessToken = 'eyJhb...2g'; // Access Token
const fetchLogtoApplications = async () => {
return await fetch(`${logtoEndpoint}/api/applications`, {
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
};
curl --location \
--request GET 'https://your.logto.endpoint/api/applications' \
--header 'Authorization: Bearer eyJhbG...2g'
อย่าลืมแทนที่ค่าตัวอย่างด้วยค่าของคุณเอง ค่าหลัง Bearer
ควรเป็นโทเค็นการเข้าถึง (JWT) ที่คุณได้รับ
ใช้โทเค็นการเข้าถึงที่ขอมากับทรัพยากร API https://shopping.api
เพื่อดึงสินค้าทั้งหมดใน shopping API:
- Node.js
- cURL
const apiEndpoint = 'https://your.api.endpoint';
const accessToken = 'eyJhb...2g'; // โทเค็นการเข้าถึง
const fetchProducts = async () => {
return await fetch(`${apiEndpoint}/products`, {
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
};
curl --location \
--request GET 'https://your.api.endpoint/products' \
--header 'Authorization: Bearer eyJhbG...2 # โทเค็นการเข้าถึง
การอนุญาต (Authorization)
หากคุณปกป้องทรัพยากร API ของคุณเองที่ไม่ใช่ Logto Management API คุณต้องพัฒนา logic การอนุญาตในบริการ API ของคุณเพื่อยืนยันโทเค็นการเข้าถึงและตรวจสอบว่าแอป M2M มีสิทธิ์ที่จำเป็นในการเข้าถึงทรัพยากรหรือไม่
ดูรายละเอียดเพิ่มเติมได้ที่ การอนุญาต (Authorization) และ ตรวจสอบความถูกต้องของโทเค็นการเข้าถึง