認證說明(JWT)
LifeERP API 採 Bearer JWT 認證。流程分兩段:用一組長期憑證(ClientId + CheckValue)向 getToken 端點換取短期存取權杖(access_token),之後所有 API 都帶這個權杖呼叫。
sequenceDiagram
participant C as 你的系統
participant T as getToken 端點
participant A as LifeERP API
C->>T: POST /api/v1/token/getToken<br/>{ClientId, CheckValue}
T-->>C: { retval.access_token }
C->>A: POST /api/v2/...<br/>Authorization: Bearer access_token
A-->>C: 業務資料
Note over C,A: 權杖到期 → 重新呼叫 getToken
一、憑證從哪來
ClientId 與 CheckValue 由 LifeCOM 開通核發,請洽技術窗口 service@lifecom.com.tw。
| 憑證 | 範例 | 性質 |
|---|---|---|
ClientId | lifecom | 識別你的應用程式 |
CheckValue | <YOUR_CHECK_VALUE> | 簽章驗證值,等同密鑰 |
:::danger 憑證保護
CheckValue 等同密碼。請:
- 只放在後端環境變數或密鑰管理服務(如 AWS Secrets Manager)。
- 絕不寫進前端、行動 App、公開版控或日誌。
- 若疑似外洩,立即聯絡 LifeCOM 重新核發。 :::
二、簽發存取權杖
端點
POST /api/v1/token/getToken
Content-Type: application/json
請求
{
"ClientId": "lifecom",
"CheckValue": "<YOUR_CHECK_VALUE>"
}
回應
{
"done": true,
"msg": "ok",
"retval": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
| 欄位 | 型別 | 說明 |
|---|---|---|
done | boolean | 是否成功 |
msg | string | 訊息(失敗時含原因) |
retval.access_token | string | 後續 API 要用的 JWT |
三、帶權杖呼叫 API
把 access_token 放進 Authorization 標頭,格式為 Bearer <token>:
curl -X POST https://oms.lifecom.com.tw/api/v2/default/getStocksData/searchList \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{ "products_stock.warehouse_no": 1 }'
四、範例:Node.js 封裝
以下示範把「取得權杖 + 帶權杖呼叫」封裝成可重用的客戶端,並在權杖失效時自動重取:
const BASE_URL = "https://oms.lifecom.com.tw";
let cachedToken = null;
async function getToken() {
const res = await fetch(`${BASE_URL}/api/v1/token/getToken`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
ClientId: process.env.LIFEERP_CLIENT_ID,
CheckValue: process.env.LIFEERP_CHECK_VALUE,
}),
});
const data = await res.json();
if (!data.done) throw new Error(`取得權杖失敗:${data.msg}`);
cachedToken = data.retval.access_token;
return cachedToken;
}
async function callApi(path, body, retry = true) {
const token = cachedToken ?? (await getToken());
const res = await fetch(`${BASE_URL}${path}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify(body),
});
// 權杖過期 → 重取一次再試
if (res.status === 401 && retry) {
cachedToken = null;
return callApi(path, body, false);
}
return res.json();
}
// 用法
const stock = await callApi("/api/v2/default/getStocksData/searchList", {
"products_stock.warehouse_no": 1,
});
五、權杖生命週期與最佳實務
- 重複使用:權杖在有效期內可重複使用,不需要每支 API 都重新簽發。
- 快取:將權杖快取於記憶體(如上例的
cachedToken),降低getToken呼叫量。 - 被動刷新:收到
401 Unauthorized時清掉快取、重新getToken後重試一次。 - 避免並發風暴:多執行緒/多實例環境下,建議對
getToken加上互斥鎖或集中式快取(如 Redis),避免同時大量重簽。
六、常見錯誤
| 狀況 | 可能原因 | 處理 |
|---|---|---|
done: false、getToken 失敗 | ClientId / CheckValue 錯誤或未開通 | 核對憑證、聯絡技術窗口 |
401 Unauthorized | 權杖過期或未帶 Bearer 前綴 | 重新簽發權杖;確認標頭格式 |
403 Forbidden | 該帳號無此端點權限 | 聯絡 LifeCOM 開通對應權限 |