登入
Mini App 可以用 Micromeet 帳號讓正在使用 Cowork 的人登入,再從它自己的後端以這個人的身分呼叫 Micromeet。頁面始終拿不到密碼、token 或 Mini App 的金鑰:Cowork 只給頁面一個一次性的 code,由 Mini App 的後端拿它換 token。
只有 Micromeet 簽章過、而且至少有一個驗證過的伺服器網域的已安裝 Mini App 能讓人登入(請見打包與簽章)。內建 Mini App 沒有這個模組。
MAESTROSDK.auth.login(params?) 尚未發布
向 Cowork 要一個一次性 code,對應這個 Mini App 和目前登入 Cowork 的人。
參數
| 欄位 | 類型 | 必填 | 說明 |
|---|---|---|---|
scopes | string[] | 否 | Mini App 要的權限,例如 ['profile:read']。不傳就是 Micromeet 允許這個 Mini App 的全部權限 |
第一次呼叫時,Cowork 會給這個人看一張卡:Mini App 的名稱和開發者、它要的權限、將要使用的帳號;按鈕是 授權 和 取消,預設是取消。卡片只出現在這個人正在看的分頁上。授權過一次之後,同樣的權限再呼叫會直接拿到 code,不再跳出卡片。
回傳值
Promise<{ ok: true; code: string; region: 'SG' | 'HK' | 'ID'; expiresIn: number } | { ok: false; error: string }>
code 只能用一次,5 分鐘內有效(expiresIn 單位為秒)。把 code 和 region 傳給你的後端。
error | 意思 |
|---|---|
unsigned | 封裝沒有 Micromeet 的簽章,或頁面不是已安裝的 Mini App |
tampered | 安裝後 Mini App 的檔案被改過;Cowork 已關閉它 |
host_signed_out | 沒有人登入 Cowork,或頁面是為另一個帳號開啟的。如果這正是使用者在看的分頁,Cowork 會開啟它的登入畫面 |
user_cancelled | 使用者取消、分頁在背景,或卡片開著時換了帳號 |
app_not_available | 這個 AppID 在本區沒有登記,或已停用 |
version_not_available | 這個版本沒有登記或已停用:請更新 Mini App |
no_server_domain | 這個版本沒有驗證過的伺服器網域,或其中有網域已不再有效(請見打包與簽章) |
scope_denied | 要了 Micromeet 沒有允許這個 Mini App 的權限,或 scopes 不是字串清單 |
rate_limited | 一分鐘內要的 code 太多;請稍後再試 |
network | Cowork 連不上 Micromeet |
MAESTROSDK.auth.status() 尚未發布
Promise<{ signed: boolean; host: 'cowork'; hostSignedIn: boolean }>。封裝的簽章有效且檔案都沒被改過時 signed 為 true;有人登入 Cowork 時 hostSignedIn 為 true。可以依此決定要不要顯示登入按鈕。
在 Mini App 的後端
後端保存 Micromeet 登記 AppID 時給的 client secret,Mini App 登記在幾個區就有幾組;不要放進頁面或封裝裡。後端執行在 Mini App 驗證過的某個伺服器網域上(請見打包與簽章)。一步步的範例請見開發登入 Mini App。
頁面送來的請求
頁面的 origin 是 miniapp://<appId>。回應它的請求時帶上 Access-Control-Allow-Origin: miniapp://<appId>,預檢請求(OPTIONS)也要允許它用到的方法和請求標頭;否則請求在頁面裡就失敗了,到不了你的程式。Micromeet 的 token 留在後端,給頁面你自己的工作階段。
後端工具
@micromeet-ai/miniapp-sdk/server:ESM 和 CommonJS 都能用,需要 Node.js 18 或更新版本。
import { createMiniappAuthClient, MiniappAuthError } from '@micromeet-ai/miniapp-sdk/server';
const auth = createMiniappAuthClient({ appId: 'ai.example.app', clientSecret: process.env.MINIAPP_SECRET_HK });
const tokens = await auth.exchangeCode({ code, region });
const me = await auth.profile({ accessToken: tokens.accessToken, region: tokens.region });| 選項 | 必填 | 說明 |
|---|---|---|
appId | 是 | AppID |
clientSecret | 是 | 這個 client 要呼叫的那個區的 secret;每個區建立一個 client |
coreUrl | 否 | (region) => 位址:呼叫哪個 Micromeet。預設依區呼叫正式環境 |
fetch | 否 | 取代全域的 fetch |
timeoutMs | 否 | 每個請求的逾時,預設 15000 |
| 函式 | 回傳 |
|---|---|
exchangeCode({ code, region }) | token:accessToken、expiresIn(秒)、refreshToken、scope(清單)、user: { ref, name, email }、institution: { iid, name }、region |
refresh({ refreshToken, region }) | 一組新的 token;舊的 refresh token 失效,保存新的 |
revoke({ refreshToken, region }) | 無;讓這個人登出 Mini App |
profile({ accessToken, region }) | { ref, name, email, institution: { iid, name }, region }(profile:read) |
call({ accessToken, region, path, body? }) | 向接受 Mini App token 的 Micromeet 介面送出 POST,回傳它的 data |
出錯時每個函式都會拋出 MiniappAuthError,帶有 Micromeet 的 code 和 HTTP status(請見下面的「錯誤」)。
Token
| Token | 有效期限 | 用途 |
|---|---|---|
| Access token | 15 分鐘 | 呼叫接受 Mini App token 的介面時放在 Authorization: Bearer |
| Refresh token | 30 天 | refresh 換一組新的;每個 refresh token 只能用一次 |
- 之後的每次呼叫都用 code 帶來的那個區;token 只在它的區有效。
- token 代表這個人,以及他登入時在 Cowork 裡選取的機構。
user.ref是這個人在這個 Mini App 裡的固定編號(換一個 Mini App 就是另一個):用它當你的使用者鍵值。- 變更密碼、登出所有裝置、離開機構、版本停用或 Mini App 停用後,token 在下一次請求時失效。
Scope 與介面
| Scope | 介面 | 回傳 |
|---|---|---|
profile:read | POST /share/miniapp/profile | { ref, name, email, institution: { iid, name }, region } |
token 只能用在這張表裡的介面上,只限這個人授權的 scope,也不會超出這個人在 Micromeet 裡本來能做的事。
錯誤
code | HTTP | 發生了什麼 |
|---|---|---|
invalid_client | 401 | 這個區的 AppID 或 secret 不對,或 secret 已被更換 |
invalid_grant | 400 | code 已用過、超過 5 分鐘或不是這個 AppID 的;refresh token 已用過、已撤銷或超過 30 天;或這個人變更了密碼、登出了所有裝置、離開了機構:重新登入 |
app_not_available | 400 | 這個 Mini App 在這個區已停用 |
version_not_available | 400 | 這個人登入時用的版本已停用:請更新 Mini App |
needLogin | 401 | 呼叫介面時:access token 過期或已失效。呼叫 refresh,失敗就重新登入 |
forbidden | 403 | 呼叫介面時:token 沒有這個介面的 scope,或這個人在 Micromeet 裡不能做這件事 |
network | — | 後端工具連不上 Micromeet(status 為 0) |
params_invalid | 400 或 — | grant_type 不對;或後端工具收到未知的區、不是介面的 path(status 為 0,不送出請求) |
HTTP 呼叫
其他語言的後端做同樣的呼叫。每個都是向 code 所在區的 Micromeet 送出 POST,請求本文是 JSON:
| 區 | 位址 |
|---|---|
| SG | https://crms-api.micromeet.ai |
| HK | https://crms-api-hk.micromeet.ai |
| ID | https://crms-api-id.micromeet.ai |
| 路徑 | 請求本文 | 回應裡的 data |
|---|---|---|
/miniapp-open/auth/token | { "grant_type": "authorization_code", "app_id", "client_secret", "code" } | { access_token, token_type: "Bearer", expires_in, refresh_token, scope, user: { ref, name, email }, institution: { iid, name }, region };scope 以空格分隔 |
/miniapp-open/auth/token | { "grant_type": "refresh_token", "app_id", "client_secret", "refresh_token" } | 同上 |
/miniapp-open/auth/revoke | { "app_id", "client_secret", "refresh_token" } | { revoked: true } |
/share/miniapp/profile | {},帶 Authorization: Bearer <access_token> | { ref, name, email, institution: { iid, name }, region } |
成功時回應 { "code": 0, "success": true, "data": … };失敗時回應 { "code": "<錯誤>", "msg": "…", "success": false },HTTP 狀態請見上面的「錯誤」。