
最後更新:2026 年 7 月 20 日
Quire OAuth 2.0 API 讓你的應用程式無需儲存密碼,也能代用戶操作其 Quire 帳戶。你需要一個已註冊的 OAuth 應用程式(client ID、secret、重新導向網址)、四步授權流程(設定、重新導向、處理回應、以授權碼換取 token),以及 refresh token 循環,因為 access token 會在一小時後過期。
開發一個讀取或修改用戶 Quire 資料的應用程式,第一個決定就是:如何在完全不接觸用戶密碼的情況下完成驗證?Quire API 以 OAuth 2.0 解決這個問題。本文會逐步介紹 OAuth 應用程式設定、四步授權流程、access token 與 refresh 循環,以及開發者首次建置時常犯的錯誤。
Quire OpenAPI 的 1.0.0 版本已於 2019 年 10 月推出,之後一直保持穩定。透過 OAuth,用戶授權你的應用程式存取其 Quire 內容(任務、專案、留言、指派、標籤、到期日期),而你完全不會接觸他們的憑證。
用戶可隨時撤銷存取權限,無需更改密碼。這正是在 OAuth 出現前,儲存密碼的整合方式屬於安全反模式,而 OAuth 令它變得不再必要的原因。
在串接 OAuth API 之前,先確認 API 真的是合適的工具。2026 年的 Quire 提供四種受支援的整合介面,各自解決不同的問題。
| 如果你需要… | 使用 | 原因 |
|---|---|---|
| 在自己的應用程式中代用戶讀取或修改 Quire 資料 | Quire OAuth API(本文) | 用戶授權、完整 CRUD 存取、無需輪詢 |
| 對 Quire 中的事件作出反應(任務已建立、狀態已變更、已新增留言) | Quire Webhooks | 以推送為主、無輪詢負擔、設定輕巧 |
| 將 Quire 連接到 Claude 或其他 AI 代理 | Quire MCP 伺服器 | LLM 工具的標準協定,附有預先建置的伺服器 |
| 將 Quire 接入自動化或 BI 工作流程 | OAuth API 配合 n8n 或 Power BI | 成熟的管線,自訂程式碼較少 |
如果你要開發典型的應用程式整合(流動應用程式、網頁儀表板、同步服務),OAuth API 就是你要的。本文其餘部分均假設你走這條路線。
要使用 Quire API,你需要先建立一個 OAuth 應用程式。
你需要先登入 Quire 帳戶,才能建立應用程式。
前往 Quire 開發者應用程式控制台,然後按一下 建立新的應用程式 按鈕。

選擇應用程式所屬的 Quire組織,該組織的成員可以檢視及編輯屬於所選組織的所有應用程式。

為你的應用程式命名,並填寫重新導向網址,我們稍後會說明重新導向網址的作用。現階段你可以先填入以下網址:
http://localhost:3000/callback
按一下 建立新的應用程式 按鈕,新建立的 OAuth 應用程式就會顯示在開發者控制台頁面,讓你作進一步設定。

總括而言,你應該已取得以下三項資料:
http://localhost:3000/callback
在應用程式中存放你的應用程式設定資料。
const clientId = ':wJoMEodI4fSSR54pfNwIuIzLnaJ';
const clientSecret = 'eb8faf4nyd1wbeconw060e9ejui8zg6w8p1hyoex';
const redirectURI = 'http://localhost:3000/callback';
const authorizationUrl = 'https://quire.io/oauth';
const tokenUrl = 'https://quire.io/oauth/token';
const apiUrl = 'https://quire.io/api';產生一個授權網址,把用戶重新導向至 Quire 的 OAuth 端點 URI。這會顯示一個網頁,讓已登入的 Quire 用戶授權你的應用程式存取其內容。
範例網址:
https://quire.io/oauth?client_id=your-client-ID&redirect_uri=your-redirect-uri授權連結的檢視範例如下:
var http = require('http');
var url = require('url');
var server = http.createServer(function (req, res) {
var uri = url.parse(req.url, true);
if (uri.pathname == '/') {
//..
} else if (uri.pathname == "/install") {
var authUrl = authorizationUrl
+ '?client_id=' + clientId
+ '&redirect_uri=' + encodeURIComponent(redirectURI);
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write(
'<html><body>'
+ '<a href="' + authUrl + '">Connect Quire</a>'
+ '</body></html>');
res.end();
} else if (uri.pathname == "/callback") {
//...
}
});
server.listen(3000);state 參數是一串隨機字串,用來防範跨站請求偽造(CSRF)攻擊。你應該隨機產生一串字元,它會在步驟 3 原封不動地傳回你的應用程式,而你的應用程式應驗證這個值。雖然此參數為選填,但我們強烈建議加入。
範例網址:
https://quire.io/oauth?client_id=your-client-ID&redirect_uri=your-redirect-uri&state=lpcl9v94zOAuth 2.0 伺服器會透過 redirect_uri 所指定的網址,回應你的應用程式的存取請求。
如果用戶核准存取請求,回應會包含一個授權碼;如果用戶不核准,回應則包含錯誤訊息。傳回網頁伺服器的授權碼或錯誤訊息會出現在查詢字串中,如下所示:
錯誤回應:
http://localhost:3000/callback?error=access_denied授權碼回應:
http://localhost:3000/callback?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7回呼的範例如下:
//...
} else if (uri.pathname == "/callback") {
var result = uri.query;
var message = 'Auth fail';
if (result["error_description"] != null) {
message = result["error_description"];
if (result["error"] == 'access_denied') {
//display reject message
}
messageView(res, message);
} else if (result["code"] != null) {
return exchangeAccessToken(result["code"])
.then(function(data) {
var token = data['access_token'];
message = token != null ? 'Success': 'Fail';
messageView(res, message);
});
}
}當用戶被重新導向回你的應用程式 redirect_uri 時,查詢字串參數中也會附有 code 和 state 參數。state 是你的 CSRF 防偽造 token,用來驗證請求。
從查詢字串參數中取出 code 和 state。此時可以驗證 state。
驗證的範例如下:
} else if (result["code"] != null) {
if (result["state"] != stateFromSession(res))
return messageView(res, 'invalid state');
return exchangeAccessToken(result["code"])
.then(function(data) {
var token = data['access_token'];
message = token != null ? 'Success': 'Fail';
messageView(res, message);
});
}你的應用程式需要使用取出的授權碼和以下的請求參數,向 token 端點發出 POST 呼叫。
| 參數 | 值 |
|---|---|
| grant_type | authorization_code |
| code | {your-authorization-code} |
| client_id | {your-client-ID} |
| client_secret | {your-client-secret} |
| redirect_uri | 如果你在步驟 2 指定了 redirect_uri,則為必填。此值必須與當時使用的值完全相同。 |
請求 access token 的範例如下:
var request = require('request');
function exchangeAccessToken(code) {
return new Promise(function(resolve, reject){
request.post({
url: tokenUrl,
form: {
grant_type: 'authorization_code',
code: code,
client_id: clientId,
client_secret: clientSecret,
redirect_uri: redirectURI
}
},
function (error, httpResponse, body) {
if (error) {
return reject(error);
}
resolve(JSON.parse(body))
});
});
}你收到的 access token 回應為 JSON 格式。
回應範例:
{
"access_token":"ACCESS_TOKEN",
"token_type": "bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN"
}請妥善並長期保存此 token,因為存取每一個 Quire API 都需要用到它。
你的應用程式現在已有 access token,可用來代用戶進行 API 呼叫。
進行 API 呼叫時,把 access token 作為 bearer token 放在請求的標頭中。
API 呼叫的範例如下:
function getCurrentUser(token) {
return new Promise(function(resolve, reject){
request.get({
url: apiUrl + '/user/id/me',
headers: {
"Authorization": "Bearer " + token
}
},
function (error, httpResponse, body) {
if (error) {
return reject(error);
}
resolve(JSON.parse(body))
});
});
}回應範例:
{
"email": "john@gmail.cc",
"website": "https://coolwebsites.com",
"id": "My_ID",
"description": "This is *cool*!",
"url": "https://quire.io/u/My_ID",
"nameText": "My Name",
"nameHtml": "My Name",
"descriptionText": "This is cool!",
"descriptionHtml": "This is <i>cool</i>!",
"image": "https://quire.s3.amazonaws.com/oid/image.jpg",
"iconColor": "37",
"name": "My Name",
"oid": "Dyh2YkFcu9uLgLFIeN1kB4Ld"
}Access token 刻意設計為只供短期使用,這是 OAuth 2.0 的重要安全機制。使用授權碼授權流程(Authorization Code Grant Flow)時,access token 預設的有效期為一小時。
Access token 過期時,會傳回 HTTP 401 錯誤:
{
code: 401,
message: 'Invalid or expired token.'
}你的應用程式需要重新整理 access token。
function refreshToken(refreshToken) {
return new Promise(function(resolve, reject){
request.post({
url: tokenUrl,
form: {
grant_type: 'refresh_token',
refresh_token: refreshToken,
client_id: clientId,
client_secret: clientSecret
}
},
function (error, httpResponse, body) {
if (error) {
return reject(error);
}
resolve(JSON.parse(body))
});
});
}另外,你的應用程式也可以把用戶重新導向至驗證流程。
觀察過不少團隊使用 Quire API 開發後,同樣的五個問題一再出現。它們都不難理解,也全部可以避免。
1. 把 client secret 放在用戶端程式碼中。 Client secret 顧名思義就是機密。一旦它出現在流動應用程式的執行檔或瀏覽器的 bundle 裏,任何人都能取出並冒充你的應用程式。Secret 只應存放在你控制的伺服器上。如果你的應用程式純粹在用戶端運行(單頁應用程式、流動應用程式),請改用 OAuth 2.0 PKCE 流程,而不是內嵌 secret。
2. 忘記驗證 state 參數。 state 參數的作用是防範 CSRF 攻擊。如果在回呼時略過驗證,就會留下漏洞,惡意網站可藉此悄悄把某個 Quire 帳戶與攻擊者的應用程式工作階段連結起來。請為每個請求各自產生 state,儲存在工作階段中,並拒絕任何所傳回 state 不吻合的回呼。
3. 把 access token 當作永久有效。 Access token 會在一小時後過期。儲存 token 卻從不重新整理的應用程式,第一天運作正常,第二天就會悄然失效。請在上線前就建立好 refresh token 循環,不要等到用戶投訴才「打補釘」。
4. 以輪詢方式查詢 API 的變更。 輪詢會白白耗用速率限制、增加延遲,也會耗電。如果你需要對 Quire 中的變更作出反應,請改用 Webhooks。Webhook 會即時把事件推送給你,原本用來偵測該事件的 API 呼叫也就根本無需發生。
5. 略過重新導向網址的允許清單。 每個 OAuth 應用程式註冊都接受一份重新導向網址清單。如果你使用萬用字元,或沒有精確設定,攻擊者就能把他們的回呼註冊為你的重新導向目標,進而攔截授權碼。請只加入你的應用程式實際使用的確切網址。
如果你是第一次使用 API 開發,最快掌握這些模式的方法,就是複製一個現有的整合,例如 n8n 連接器,研究它如何處理驗證、重新整理和錯誤狀態。
以下三種情況,你應該改用其他整合介面。
如果以上情況都不適用,OAuth API 就是你要用的工具。
不需要。Quire API 適用於所有方案,包括免費方案。所有方案均設有速率限制,請參閱 API 文件,了解目前每個應用程式的限制。
API 以 HTTP 為基礎,請求和回應內容均為 JSON,因此只要有 HTTP 用戶端和 JSON 解析器的語言都能使用。本文的範例以 JavaScript 撰寫,但同樣的流程在 Python、Go、Ruby、PHP 及任何其他語言中都完全一樣。官方並無提供用戶端程式庫;API 的範圍很小,常見做法是在所用語言的 HTTP 用戶端之上加一層精簡的封裝。
Access token 預設在一小時後過期。Refresh token 的有效期較長,可用來取得新的 access token,無需再次提示用戶。請由第一天起就在應用程式中建立 refresh token 循環。
可以。OAuth scope 讓你只申請應用程式所需的授權。如果你的應用程式只讀取任務,就只申請讀取 scope。Quire 用戶會在授權頁面看到所申請的 scope,若覺得要求過多可以拒絕,所以過度申請會拉低轉換率。
API 是通用的 REST 介面,適用於任何想代用戶讀取或修改 Quire 資料的應用程式。MCP 伺服器則專為 Claude 和其他 LLM 代理而設:它負責處理驗證、提供標準的工具結構,讓你無需自行編寫 OAuth 程式碼。傳統的應用程式整合請用 API,LLM 代理整合則使用 MCP。
以上就是 Quire API 完整的 OAuth 2.0 流程:OAuth 應用程式設定、四步授權、access token 的使用,以及重新整理循環。開發者交付了一個可運作的整合,卻在兩天後出問題,最常見的原因就是把重新整理循環當作日後才補的修正,而沒有由第一天起就建好。
你可以前往 Quire 開發者應用程式控制台開始,或閱讀完整的 API 參考文件。如果你根本不想編寫 OAuth 程式碼,Quire MCP 伺服器會為你處理驗證,是 LLM 代理整合的合適選擇。
對於事件驅動的整合,Webhooks 通常比大部分首次 API 整合最後採用的輪詢模式更合適。而且,如果你只想快速以腳本執行一些變更,完全不想建立 OAuth 應用程式,Quire 的 CLI 可以直接在終端機執行專案管理指令。