核心概念
核心概念
本指南會幫開發者理解:你屬於哪一層擴充、走哪種整合模式、wsa 令牌裡有什麼、以及你要「用到什麼程度」。
兩種整合模式:推式 vs 拉式
平台把身份交給你,有兩條路徑。同一枚 wsa 契約,區別只在「你如何取得身份驗證資訊」。
推式(Push handoff)—— 見 03
使用者在工作空間「擴充」頁裡點開你的應用程式,平台把 wsa 拼到你的落地頁 URL 上推給你:
https://app.example.com/landing?wsa=<JWT>
https://app.example.com/landing?wsa=<JWT>
此代碼塊在浮窗中顯示
- 入口在工作空間內。
- 開發者只需在落地頁消費
?wsa=,最簡單。 - 適合:作為工作空間側邊欄裡的一個「內嵌應用程式」。
拉式(Pull / M-Auth)—— 見 04
開發者的擴充應用程式自己放一個「Login with Workspace」按鈕,使用者點擊後進入 GPTBots 登入➡️選工作空間➡️再帶回登入態。採用 OAuth2 授權碼 + PKCE:
- 入口在開發者的擴充應用程式登入頁。
- 瀏覽器只拿到一次性
code,真正的wsa由你的後端用code+ PKCE 換取,永不進瀏覽器 URL。 - 適合:開發者的擴充應用程式是獨立站點,希望提供「用 GPTBots 工作空間帳號登入」。
| 推式 Push | 拉式 Pull (M-Auth) | |
|---|---|---|
| 登入入口 | 工作空間「擴充」頁 | 你的應用程式頁面(登入按鈕) |
| 令牌怎麼到你手上 | URL ?wsa= 直接推給落地頁 |
前端拿 code,後端換 wsa |
瀏覽器是否見過 wsa |
見過(落地後須立即抹除) | 從不(更安全) |
| 需要 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(推式)/ 支援 M-Auth(拉式),你能取得身份。auth_mode = none:平台直接跳轉,URL 不帶任何驗證資訊,你收不到身份(對應ignore)。
wsa 令牌契約(JWT)
wsa 是一枚 HS256(HMAC-SHA256)簽章的 JWT,有效期 5 分鐘(exp = iat + 300)。
標準聲明
| 聲明 | 類型 | 說明 |
|---|---|---|
iss |
string | 固定 gptbots-workspace,必校 |
aud |
string | 開發者擴充應用程式 host(如 app.example.com),從註冊 URL 解析,必校 |
sub |
string | 工作空間使用者 accountId,全域唯一,可作為開發者側的使用者 ID 主鍵 |
iat |
number(秒) | 簽發時間 |
exp |
number(秒) | 過期時間,固定 iat + 300,必校 |
業務聲明
| 聲明 | 類型 | 說明 |
|---|---|---|
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": "合約審核系統"
}
{
"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只反映使用者在該工作空間的角色,建議把它當作「初次落地的預設權限對映」,你的應用程式維護自己的權限模型。
下一步:按你選的模式讀 03-推式接入 或 04-拉式登入;無論哪種,都請讀 05-令牌校驗與安全。
