
最后更新:2026 年 7 月 20 日
Quire OAuth 2.0 API 让你的应用程序无需保存密码,就能代表用户操作其 Quire 账户。你需要一个已注册的 OAuth 应用程序(客户端 ID、密钥、重新导向网址)、一套四步授权流程(配置、重定向、处理响应、用授权码换取令牌),以及一个刷新令牌循环,因为访问令牌会在一小时后过期。
为应用程序读取或修改用户的 Quire 数据,首先要做一个决定:如何在完全不接触用户密码的情况下完成身份验证?Quire API 的答案是 OAuth 2.0。本文将带你走完 OAuth 应用程序设置、四步授权流程、访问令牌与刷新循环,以及开发者首次构建时常见的出错方式。
Quire OpenAPI 的 1.0.0 版本于 2019 年 10 月发布,此后一直保持稳定。借助 OAuth,用户授权你的应用程序访问其 Quire 内容(任务、项目、评论、分配、标签、到期日期),而你从不接触他们的凭据。用户可随时撤销该访问,无需修改密码。这也是为什么在 OAuth 出现之前,保存密码的集成方式属于安全反模式,而如今已无必要。
在接入 OAuth API 之前,先确认 API 确实是合适的工具。2026 年,Quire 支持四种集成方式,各自解决不同的问题。
| 如果你需要…… | 使用 | 原因 |
|---|---|---|
| 在你自己的应用程序中代表用户读取或修改 Quire 数据 | Quire OAuth API(本文) | 用户授权、完整的增删改查权限、无需轮询 |
| 响应 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 防伪令牌。
从查询字符串参数中提取 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);
});
}你的应用程序需要向令牌端点发起 POST 调用,并带上提取到的授权码和下列请求参数。
| 参数 | 值 |
|---|---|
| grant_type | authorization_code |
| code | {your-authorization-code} |
| client_id | {your-client-ID} |
| client_secret | {your-client-secret} |
| redirect_uri | 如果你在步骤 2 中指定了 redirect_uri,则此项必填。其值必须与步骤 2 中使用的完全一致。 |
请求访问令牌的示例如下:
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))
});
});
}你收到的访问令牌响应为 JSON 格式。
响应示例:
{
"access_token":"ACCESS_TOKEN",
"token_type": "bearer",
"expires_in":2592000,
"refresh_token":"REFRESH_TOKEN"
}请妥善且长期保存该令牌,因为访问每一个 Quire API 都需要它。
你的应用程序现在拥有了访问令牌,可以代表用户调用 API。
调用 API 时,把访问令牌作为 bearer 令牌放在请求头中。
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"
}访问令牌本来就只用于短期使用,这是 OAuth 2.0 的一项重要安全机制。使用授权码授权流程时,访问令牌默认的有效期为一小时。
访问令牌过期后,会返回 HTTP 401 错误:
{
code: 401,
message: 'Invalid or expired 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. 把客户端密钥存放在客户端代码中。 客户端密钥顾名思义就是机密。如果它出现在移动应用程序的二进制文件或浏览器的打包文件中,任何人都能提取并冒充你的应用程序。密钥只应存放在你控制的服务器上。如果你的应用程序纯属客户端(单页应用程序、移动应用程序),请改用 OAuth 2.0 PKCE 流程,而不是嵌入密钥。
2. 忘记验证 state 参数。 state 参数的作用是防止 CSRF 攻击。如果在回调时跳过验证,就留下了一个漏洞,恶意网站可以借此悄悄把某个 Quire 账户与攻击者的应用程序会话关联起来。请为每次请求生成 state,存入会话,并拒绝任何返回的 state 与之不匹配的回调。
3. 把访问令牌当作永久有效。 访问令牌会在一小时后过期。保存令牌却从不刷新的应用程序,第一天运行正常,第二天就会悄无声息地出故障。请在上线任何功能之前就构建好刷新令牌循环,而不是等用户抱怨后再打补丁。
4. 轮询 API 来检测变化。 轮询会白白消耗速率限制、增加延迟并耗电。如果你需要响应 Quire 中的变化,请改用 Webhooks。Webhooks 会立即把事件推送给你,原本用来检测该事件的 API 调用根本无需发生。
5. 跳过重新导向网址白名单。 每个 OAuth 应用程序注册都接受一份重新导向网址列表。如果你使用通配符,或没有精确配置,攻击者就可以把他们的回调注册为你的重定向目标,从而截获授权码。只添加你的应用程序实际使用的确切网址。
如果你是第一次基于该 API 开发,最快的学习方式是复刻一个现有的集成,例如 n8n 连接器,研究它如何处理身份验证、刷新和错误状态。
有三种情况,你应该改用其他集成方式。
如果以上情况都不适用,OAuth API 就是你要用的工具。
不需要。Quire API 适用于所有方案,包括免费方案。所有方案都有速率限制,当前每个应用程序的限额请查阅 API 文档。
该 API 基于 HTTP,请求和响应正文均为 JSON,因此任何带有 HTTP 客户端和 JSON 解析器的语言都能使用。本文的示例使用 JavaScript,但同样的流程在 Python、Go、Ruby、PHP 和任何其他语言中都完全一样。官方没有提供客户端库,因为 API 的接口范围很小,常见做法是在你所用语言的 HTTP 客户端外包一层轻量封装。
访问令牌默认在一小时后过期。刷新令牌的有效期更长,可用来获取新的访问令牌,而无需再次提示用户授权。请从第一天起就把刷新令牌循环构建到你的应用程序中。
可以。OAuth 范围(scope)让你只请求应用程序所需的权限。如果你的应用程序只读取任务,就请求读取范围。Quire 用户会在授权页面看到所请求的范围,如果觉得请求过多可以拒绝,因此过度请求会降低转化率。
API 是通用的 REST 接口,适用于任何想代表用户读取或修改 Quire 数据的应用程序。MCP 服务器专为 Claude 和其他 LLM 代理打造:它负责处理身份验证,提供标准的工具架构,让你不必自己编写 OAuth 代码。传统的应用程序集成使用 API,LLM 代理集成则使用 MCP。
以上就是 Quire API 完整的 OAuth 2.0 流程:OAuth 应用程序设置、四步授权、访问令牌的使用,以及刷新循环。开发者交付了一个能用的集成,两天后却出故障,最常见的原因就是把刷新循环当作日后再补的修复,而不是从第一天起就内置其中。
请从 Quire 开发者应用程序控制台开始,或阅读完整的 API 参考文档。如果你根本不想编写 OAuth 代码,Quire MCP 服务器会替你处理身份验证,是 LLM 代理集成的合适之选。
对于事件驱动的集成,Webhooks 通常比大多数首次 API 集成最终采用的轮询模式更合适。如果你只想快速执行一些修改脚本而完全不构建 OAuth 应用程序,Quire 的 CLI 可以直接在终端中运行项目管理命令。