เริ่มต้นอย่างรวดเร็ว

เริ่มต้นอย่างรวดเร็ว

ใช้โค้ดน้อยที่สุดเพื่อรัน「การจับมือยืนยันตัวตน (identity handoff)」ครบวงจรหนึ่งครั้ง เมื่อผู้ใช้ในพื้นที่ทำงานคลิกเปิดแอปส่วนขยายขององค์กรคุณ ระบบจะส่งข้อมูลตัวตนมาให้ ทำให้แบ็กเอนด์ของแอปส่วนขยายของนักพัฒนาสามารถระบุตัวตนของผู้ใช้ปัจจุบันได้อย่างถูกต้อง และดึงข้อมูลตัวตนของผู้ใช้ได้

บทเรียนอย่างรวดเร็วต่อไปนี้ใช้โหมด Push (แบบผลัก) เพื่อสาธิตอย่างง่าย:

เตรียมการ: รับคีย์ลับ

คุณต้องได้รับ คีย์ลงลายเซ็น HS256 ของแอปส่วนขยายขององค์กรก่อน เพื่อใช้ทำการจับมือยืนยันตัวตนของแอปส่วนขยายขององค์กร

  • ให้ OWNER/ADMIN ของพื้นที่ทำงานเข้าไปที่ พื้นที่ทำงาน → การจัดการพื้นที่ → แอปส่วนขยาย แล้วคลิก「เพิ่ม」
  • ชื่อแอป, ไอคอนแอป, URL หน้าเข้าแอปapp_home_url
  • โหมดยืนยันสิทธิ์เลือก workspace_account(ต้องมีการส่งข้อมูลตัวตน)
  • หลังจากส่งข้อมูลแล้ว ระบบจะแสดง App Secret เป็นข้อความธรรมดาเพียงครั้งเดียว โปรดคัดลอกเก็บไว้ทันที เมื่อปิดแล้วจะไม่สามารถดูได้อีก ทำได้เพียงหมุนเวียนคีย์ใหม่เท่านั้น

คีย์ลับมีรูปแบบเป็น wext_ + เลขฐานสิบหก 64 หลัก(Tier 2)เก็บไว้เฉพาะที่แบ็กเอนด์ของคุณ(ตัวแปรสภาพแวดล้อม / บริการจัดการคีย์ลับ)ห้ามเขียนลงในฟรอนต์เอนด์, git หรือ log เด็ดขาด

ขั้นที่ 1: แบ็กเอนด์ — อินเทอร์เฟซตรวจสอบโทเค็น

สร้างอินเทอร์เฟซแบ็กเอนด์ใหม่ เพื่อรับ wsa ที่ฟรอนต์เอนด์ POST เข้ามา ใช้คีย์ลับตรวจสอบ และเมื่อสำเร็จจึงสร้างเซสชันของคุณเอง

// ตัวอย่าง Node / Express import express from 'express'; import { verifyWsa, WsaVerificationError } from '@gptbots/workspace-extension-verify'; const app = express(); app.use(express.json()); app.post('/session/exchange', (req, res) => { try { const identity = verifyWsa(req.body.wsa, { secret: process.env.EXTENSION_APP_SECRET, // คีย์ลับของคุณ (เฉพาะที่แบ็กเอนด์) audience: 'app.example.com', // host ของแอปคุณ ต้องเท่ากับ aud ในโทเค็น }); // identity = { accountId, role, workspaceId, username?, email?, avatar?, appName?, issuedAt?, expiresAt? } const sid = createYourSession(identity); // เปลี่ยนเป็น session ของคุณเอง res.cookie('sid', sid, { httpOnly: true, secure: true, sameSite: 'lax' }); res.json(identity); } catch (e) { const code = e instanceof WsaVerificationError ? e.code : 'Error'; res.status(401).json({ code }); // ตรวจสอบไม่ผ่านให้ปฏิเสธทั้งหมด } });
                      
                      // ตัวอย่าง Node / Express
import express from 'express';
import { verifyWsa, WsaVerificationError } from '@gptbots/workspace-extension-verify';

const app = express();
app.use(express.json());

app.post('/session/exchange', (req, res) => {
  try {
    const identity = verifyWsa(req.body.wsa, {
      secret: process.env.EXTENSION_APP_SECRET, // คีย์ลับของคุณ (เฉพาะที่แบ็กเอนด์)
      audience: 'app.example.com',              // host ของแอปคุณ ต้องเท่ากับ aud ในโทเค็น
    });
    // identity = { accountId, role, workspaceId, username?, email?, avatar?, appName?, issuedAt?, expiresAt? }

    const sid = createYourSession(identity);    // เปลี่ยนเป็น session ของคุณเอง
    res.cookie('sid', sid, { httpOnly: true, secure: true, sameSite: 'lax' });
    res.json(identity);
  } catch (e) {
    const code = e instanceof WsaVerificationError ? e.code : 'Error';
    res.status(401).json({ code });             // ตรวจสอบไม่ผ่านให้ปฏิเสธทั้งหมด
  }
});

                    
บล็อกโค้ดนี้ในหน้าต่างลอย

verifyWsa จะตรวจสอบตามลำดับ: ลายเซ็น → issaudexp(รวม iat/nbf)→ claim ที่จำเป็น หากข้อใดข้อหนึ่งไม่ผ่านจะโยน WsaVerificationError ดูรายละเอียดที่ 06-SDK-API-อ้างอิง

ขั้นที่ 2: ฟรอนต์เอนด์ — หน้า Landing ที่บริโภคโทเค็น

ผู้ใช้จะถูกแพลตฟอร์มนำไปที่ app_home_url?wsa=<JWT> ของคุณ บนหน้า Landing นี้ ให้อ่าน wsa, POST ไปยังแบ็กเอนด์ของคุณเอง จากนั้นลบมันออกจาก URL

// หน้า Landing ของคุณ import { consumeHandoff } from '@gptbots/workspace-extension-sdk'; const identity = await consumeHandoff({ exchangeUrl: '/session/exchange' }); // consumeHandoff ทำตามลำดับดังนี้: // 1) อ่าน ?wsa= จาก URL ปัจจุบัน // 2) POST { wsa } ไปยัง /session/exchange (แบ็กเอนด์ของคุณ verifyWsa ที่นี่) // 3) เมื่อสำเร็จ ใช้ history.replaceState ลบ ?wsa= ออกจาก URL // 4) คืนค่า identity ที่แบ็กเอนด์ส่งกลับมา console.log('ผู้ใช้พื้นที่ทำงานปัจจุบัน:', identity.username, identity.role); if (identity.role === 'MEMBER') hideAdminUI();
                      
                      // หน้า Landing ของคุณ
import { consumeHandoff } from '@gptbots/workspace-extension-sdk';

const identity = await consumeHandoff({ exchangeUrl: '/session/exchange' });
// consumeHandoff ทำตามลำดับดังนี้:
// 1) อ่าน ?wsa= จาก URL ปัจจุบัน
// 2) POST { wsa } ไปยัง /session/exchange (แบ็กเอนด์ของคุณ verifyWsa ที่นี่)
// 3) เมื่อสำเร็จ ใช้ history.replaceState ลบ ?wsa= ออกจาก URL
// 4) คืนค่า identity ที่แบ็กเอนด์ส่งกลับมา

console.log('ผู้ใช้พื้นที่ทำงานปัจจุบัน:', identity.username, identity.role);
if (identity.role === 'MEMBER') hideAdminUI();

                    
บล็อกโค้ดนี้ในหน้าต่างลอย

เพียงเท่านี้ โค้ดสองส่วนก็ทำการจับมือยืนยันตัวตนอย่างปลอดภัยได้สำเร็จ

แผนผังลิงก์ครบวงจร

หน้า「ส่วนขยาย」ของพื้นที่ทำงาน แพลตฟอร์ม GPTBots แอปของคุณ ──────────────── ─────────── ──────── ผู้ใช้คลิกไอคอนแอปของคุณ ───────────────▶ ตรวจสอบว่าผู้คลิกเป็นสมาชิกของพื้นที่ทำงานนี้ ใช้คีย์ลับลงลายเซ็น wsa (JWT) อายุ 5 นาที เปิด https://app.example.com/?wsa=<JWT> ────────────────────────────▶ หน้า Landing consumeHandoff() ◀── POST /session/exchange { wsa } ── แบ็กเอนด์ของคุณ verifyWsa() → identity สร้าง session ของตัวเอง ลบ ?wsa= ออกจาก URL
                      
                      หน้า「ส่วนขยาย」ของพื้นที่ทำงาน           แพลตฟอร์ม GPTBots         แอปของคุณ
────────────────                         ───────────                ────────
ผู้ใช้คลิกไอคอนแอปของคุณ ───────────────▶ ตรวจสอบว่าผู้คลิกเป็นสมาชิกของพื้นที่ทำงานนี้
                                          ใช้คีย์ลับลงลายเซ็น wsa (JWT) อายุ 5 นาที
เปิด https://app.example.com/?wsa=<JWT> ────────────────────────────▶ หน้า Landing
                                                                     consumeHandoff()
                                          ◀── POST /session/exchange { wsa } ──
                                                                     แบ็กเอนด์ของคุณ verifyWsa() → identity
                                                                     สร้าง session ของตัวเอง
                                                                     ลบ ?wsa= ออกจาก URL

                    
บล็อกโค้ดนี้ในหน้าต่างลอย

เคล็ดลับการเชื่อมต่อทดสอบในเครื่อง

  • wsa มีอายุเพียง 5 นาที เป็นโทเค็นนำทางแบบใช้ครั้งเดียว หลังจากแลกเป็นเซสชันของตัวเองแล้ว คำขอถัดไปไม่ต้องพก wsa มาอีก
  • audience ต้องเท่ากับ host ที่คุณลงทะเบียนไว้อย่างแม่นยำ(app.example.com)พอร์ต/โปรโตคอลไม่นับเป็นส่วนของ aud แต่ host ต้องตรงกัน ไม่เช่นนั้นจะได้ WrongAudience
  • ตรวจสอบไม่ผ่านให้ดู WsaVerificationError.code ก่อน(InvalidSignature / Expired / WrongAudience …)เทียบกับ 07-คำถามที่พบบ่อยและการแก้ปัญหา
  • อยากไม่สร้างเซสชัน แค่อ่านตัวตนเพื่อแสดงผล? เปลี่ยน consumeHandoff เป็น readHandoffToken() ได้เลย(ดู 02 ระดับการบริโภคสามแบบ
    ขั้นถัดไป: อ่าน 02-แนวคิดหลัก เพื่อเข้าใจสัญญาโทเค็นและสองโหมด หรือเข้า 03-การเชื่อมต่อแบบ Push / 04-การเข้าสู่ระบบแบบ Pull โดยตรงเพื่อดูรายละเอียดครบถ้วน
    เชื่อมต่อระบบเว็บของคุณเองเข้ากับพื้นที่ทำงาน GPTBots ในฐานะ「แอปส่วนขยาย」เมื่อผู้ใช้พื้นที่ทำงานเปิดแอปของคุณจาก พื้นที่ทำงาน → ส่วนขยาย (Extensions) GPTBots จะส่งมอบตัวตนในพื้นที่ทำงานของผู้ใช้ให้คุณอย่างปลอดภัยด้วยโทเค็นลงลายเซ็นอายุสั้นหนึ่งใบ(wsa ซึ่งเป็น JWT ใบหนึ่ง)แอปของคุณจึงระบุตัวตนผู้ใช้ได้โดยไม่ต้องล็อกอิน และเปิดฟังก์ชันตามบทบาทได้

นำทางสารบัญ

ไฟล์ ผู้อ่าน เนื้อหา
เริ่มต้นอย่างรวดเร็ว.md ทุกคน รันการจับมือยืนยันตัวตนครบวงจรใน 10 นาที(รวมโค้ดฟรอนต์เอนด์ + แบ็กเอนด์ขั้นต่ำที่ใช้งานได้)
แนวคิดหลัก.md ทุกคน แอปส่วนขยายสองชั้น, สองโหมดการเชื่อมต่อ, auth_mode, ระดับการบริโภคสามแบบ, สัญญาโทเค็น wsa
การเชื่อมต่อแบบ Push.md ผู้เชื่อมต่อแบบ Push ผู้ใช้คลิกเปิดแอปในหน้าส่วนขยาย → แพลตฟอร์มผลัก wsa ให้คุณ(หน้า Landing ?wsa=
การเข้าสู่ระบบแบบ Pull.md ผู้เชื่อมต่อแบบ Pull แอปของคุณวางปุ่ม「Login with GPTBots Workspace」หนึ่งปุ่ม(OAuth2 authorization code + PKCE)
การตรวจสอบโทเค็นและความปลอดภัย.md ทุกคน(ต้องอ่าน) รายการตรวจสอบบังคับ, การเก็บรักษาคีย์ลับ, การตรวจสอบหลายภาษาเมื่อไม่ใช้ SDK(Java / Node / Python)
SDK-API-อ้างอิง.md ทุกคน API, ประเภท, และรหัสข้อผิดพลาดครบถ้วนของแพ็กเกจ SDK ทั้งสองตัว
คำถามที่พบบ่อยและการแก้ปัญหา.md ทุกคน FAQ, ตารางรวมรหัสข้อผิดพลาด, ข้อผิดพลาดที่พบบ่อย

ภาพรวม SDK

SDK ทางการเป็นสองแพ็กเกจที่ไม่ผูกกับเฟรมเวิร์กและไม่มี dependency ในรันไทม์(ทั้งคู่อยู่ในไฟล์บีบอัด workspace-extension-sdk-0.1.0.zip):

ชื่อแพ็กเกจ ตำแหน่งที่รัน หน้าที่
@gptbots/workspace-extension-verify แบ็กเอนด์ของคุณ(Node) ใช้คีย์ลับตรวจสอบ wsa → ได้ WorkspaceIdentity; แบ็กเอนด์แลก codewsa
@gptbots/workspace-extension-sdk เบราว์เซอร์ อ่าน / ลบ / แลก wsa; เริ่ม「Login with GPTBots Workspace」

ไม่อยากใช้ SDK ก็ได้ — wsa เป็น HS256 JWT มาตรฐาน ไลบรารี JWT ของภาษาใดก็ตรวจสอบได้ ดูที่ 05-การตรวจสอบโทเค็นและความปลอดภัย

ติดตั้งในเครื่องจากไฟล์บีบอัด

# หลังแตกไฟล์ ทั้งสองแพ็กเกจมี dist ที่ pre-build มาแล้ว ใช้เป็น dependency ในเครื่องได้เลย: unzip workspace-extension-sdk-0.1.0.zip npm i ./workspace-extension-sdk/packages/verify # แบ็กเอนด์ npm i ./workspace-extension-sdk/packages/browser # ฟรอนต์เอนด์
                      
                      # หลังแตกไฟล์ ทั้งสองแพ็กเกจมี dist ที่ pre-build มาแล้ว ใช้เป็น dependency ในเครื่องได้เลย:
unzip workspace-extension-sdk-0.1.0.zip
npm i ./workspace-extension-sdk/packages/verify   # แบ็กเอนด์
npm i ./workspace-extension-sdk/packages/browser  # ฟรอนต์เอนด์

                    
บล็อกโค้ดนี้ในหน้าต่างลอย

หลังจาก SDK เผยแพร่ต่อสาธารณะไปยัง npm แล้ว สามารถ npm i @gptbots/workspace-extension-verify / npm i @gptbots/workspace-extension-sdk ได้โดยตรง

รายการตรวจสอบก่อนเชื่อมต่อ

  • ยืนยันแล้วว่าคุณสร้างแอปส่วนขยายขององค์กรและได้คีย์ลับที่เกี่ยวข้องแล้ว
  • กำหนดโหมดการเชื่อมต่อแล้ว: Push หรือ Pull(M-Auth)
  • host ของ app_home_url(Push)/ redirect_uri(Pull)ตรงกับข้อมูลลงทะเบียนทุกประการ
  • แบ็กเอนด์ได้ทำการตรวจสอบ wsa แล้ว: ลายเซ็น + iss + aud + exp ทั้งสี่รายการเป็นการตรวจสอบบังคับ
  • หลัง Landing ให้ history.replaceState ลบ wsa / code ออกจาก URL ทันที
  • แลกโทเค็นเป็นเซสชันของแอปเองแล้ว คำขอถัดไปไม่ส่งผ่าน wsa อีก
  • นาฬิกาเซิร์ฟเวอร์ของแอปได้ซิงค์ NTP แล้ว