แนวคิดหลัก
คู่มือนี้จะช่วยให้นักพัฒนาเข้าใจว่า: คุณอยู่ในแอปส่วนขยายชั้นใด, ใช้โหมดการเชื่อมต่อแบบไหน, ในโทเค็น wsa มีอะไร และคุณต้องการ「ใช้ถึงระดับไหน」
สองโหมดการเชื่อมต่อ: Push vs Pull
แพลตฟอร์มส่งมอบตัวตนให้คุณได้สองเส้นทาง สัญญา wsa ใบเดียวกัน ต่างกันแค่「คุณรับข้อมูลยืนยันตัวตนมาอย่างไร」
Push handoff (แบบผลัก) — ดู 03
ผู้ใช้คลิกเปิดแอปของคุณในหน้า「ส่วนขยาย」ของพื้นที่ทำงาน แพลตฟอร์มจะต่อ wsa เข้ากับ URL หน้า Landing ของคุณและผลักมาให้:
https://app.example.com/landing?wsa=<JWT>
- ทางเข้าอยู่ภายในพื้นที่ทำงาน
- นักพัฒนาเพียงบริโภค
?wsa=ที่หน้า Landing ง่ายที่สุด - เหมาะกับ: การเป็น「แอปฝังตัว」ในแถบด้านข้างของพื้นที่ทำงาน
Pull / M-Auth (แบบดึง) — ดู 04
แอปส่วนขยายของนักพัฒนาวางปุ่ม「Login with Workspace」ด้วยตัวเอง ผู้ใช้คลิกแล้วเข้าสู่การล็อกอิน GPTBots ➡️ เลือกพื้นที่ทำงาน ➡️ แล้วนำสถานะล็อกอินกลับมา ใช้ OAuth2 authorization code + PKCE:
- ทางเข้าอยู่ที่หน้าล็อกอินของแอปส่วนขยายของนักพัฒนา
- เบราว์เซอร์ได้แค่
codeแบบใช้ครั้งเดียว ส่วนwsaตัวจริงแบ็กเอนด์ของคุณเป็นผู้แลกด้วยcode+ PKCE และไม่มีวันเข้าไปใน URL ของเบราว์เซอร์ - เหมาะกับ: แอปส่วนขยายของนักพัฒนาที่เป็นเว็บไซต์อิสระ ต้องการให้บริการ「ล็อกอินด้วยบัญชีพื้นที่ทำงาน GPTBots」
| Push (แบบผลัก) | Pull (M-Auth, แบบดึง) | |
|---|---|---|
| ทางเข้าล็อกอิน | หน้า「ส่วนขยาย」ของพื้นที่ทำงาน | หน้าแอปของคุณ(ปุ่มล็อกอิน) |
| โทเค็นมาถึงมือคุณอย่างไร | URL ?wsa= ผลักตรงไปที่หน้า Landing |
ฟรอนต์เอนด์รับ code, แบ็กเอนด์แลก wsa |
เบราว์เซอร์เคยเห็น wsa ไหม |
เคย(หลัง Landing ต้องลบทันที) | ไม่เคย(ปลอดภัยกว่า) |
| ต้องใช้ PKCE ไหม | ไม่ | ใช่(บังคับ S256) |
| เมธอดฟรอนต์เอนด์ของ SDK | consumeHandoff |
startWorkspaceLogin + completeWorkspaceLogin |
คู่มือการใช้ข้อมูลยืนยันตัวตน
แพลตฟอร์มรับผิดชอบเพียง「ส่งมอบตัวตน」ส่วนการใช้หรือไม่ใช้ นักพัฒนาตัดสินใจเองอย่างอิสระ:
| ระดับ | ความหมาย | สิ่งที่นักพัฒนาต้องทำ |
|---|---|---|
use |
ตรวจลายเซ็น + สร้างเซสชัน + ควบคุมสิทธิ์ฟังก์ชันตาม role |
consumeHandoff / completeWorkspaceLogin, แบ็กเอนด์ verifyWsa |
receive-only |
อ่านตัวตนเพื่อแสดงผล/เก็บสถิติ แต่ไม่สร้างเซสชัน ไม่ควบคุมสิทธิ์ ยังใช้การยืนยันตัวตนของตัวเองหรือแบบไม่ระบุตัวตน | เพียง readHandoffToken()(ฟังก์ชันบริสุทธิ์ ไม่มีผลข้างเคียง) |
ignore |
ไม่อ่านเลย เทียบเท่า auth_mode=none คือลิงก์ภายนอกธรรมดา |
ไม่ต้องทำอะไร |
verifyWsa/readHandoffTokenล้วนเป็นฟังก์ชันบริสุทธิ์ ดังนั้น「รับแต่ไม่ใช้」จึงไม่มีต้นทุน
สอดคล้องกับ auth_mode ตอนลงทะเบียน:
auth_mode = workspace_account: แพลตฟอร์มจะลงลายเซ็นwsaแล้วต่อเข้ากับ URL(Push)/ รองรับ M-Auth(Pull)คุณจึงรับตัวตนได้auth_mode = none: แพลตฟอร์มเปลี่ยนเส้นทางตรง URL ไม่พกข้อมูลยืนยันตัวตนใด ๆ คุณจะไม่ได้รับตัวตน(สอดคล้องกับignore)
สัญญาโทเค็น wsa(JWT)
wsa เป็น JWT ที่ลงลายเซ็นแบบ HS256(HMAC-SHA256)มีอายุ 5 นาที(exp = iat + 300)
Claim มาตรฐาน
| Claim | ประเภท | คำอธิบาย |
|---|---|---|
iss |
string | คงที่เป็น gptbots-workspace, ต้องตรวจ |
aud |
string | host ของแอปส่วนขยายของนักพัฒนา(เช่น app.example.com)แยกมาจาก URL ลงทะเบียน, ต้องตรวจ |
sub |
string | accountId ของผู้ใช้พื้นที่ทำงาน ไม่ซ้ำทั่วโลก ใช้เป็นคีย์หลักของ user ID ฝั่งนักพัฒนาได้ |
iat |
number(วินาที) | เวลาที่ออกโทเค็น |
exp |
number(วินาที) | เวลาหมดอายุ คงที่เป็น iat + 300, ต้องตรวจ |
Claim ทางธุรกิจ
| Claim | ประเภท | คำอธิบาย |
|---|---|---|
role |
string | OWNER / ADMIN / MEMBER — บทบาทของผู้ใช้ในพื้นที่ทำงานนั้น |
workspace_id |
string | ID พื้นที่ทำงาน(คือ projectId), คีย์แยกผู้เช่าหลายราย |
username |
string | ชื่อเล่นผู้ใช้(อาจไม่มี) |
email |
string | อีเมลผู้ใช้(อาจไม่มี) |
avatar |
string | URL รูปโปรไฟล์(อาจไม่มี) |
app_name |
string | ชื่อแอปส่วนขยายที่สอดคล้องกับการเปลี่ยนเส้นทางครั้งนั้น(เพื่อการตรวจสอบ, อาจไม่มี) |
ฟิลด์ที่อาจไม่มี:
username/avatar/app_nameเมื่อข้อมูลต้นทางว่างเปล่าจะไม่ปรากฏใน payload โปรดจัดการค่าว่างเสมอ อย่าสมมติว่ามันจะมีอยู่แน่นอน
ตัวอย่าง payload
{
"iss": "gptbots-workspace",
"aud": "app.example.com",
"sub": "65f7c8a1d8f3a40012345678",
"iat": 1730000000,
"exp": 1730000300,
"username": "张三",
"email": "zhangsan@example.com",
"avatar": "https://cdn.example.com/avatar/u123.png",
"role": "ADMIN",
"workspace_id": "65a0000000000000000abcde",
"app_name": "合同审核系统"
}
role≠ สิทธิ์ภายในแอปของคุณroleสะท้อนเพียงบทบาทของผู้ใช้ในพื้นที่ทำงานนั้น แนะนำให้ถือว่ามันเป็น「การแมปสิทธิ์เริ่มต้นตอน Landing ครั้งแรก」ส่วนแอปของคุณดูแลโมเดลสิทธิ์ของตัวเอง
ขั้นถัดไป: อ่านตามโหมดที่คุณเลือก 03-การเชื่อมต่อแบบ Push หรือ 04-การเข้าสู่ระบบแบบ Pull; ไม่ว่าแบบใด โปรดอ่าน 05-การตรวจสอบโทเค็นและความปลอดภัย
