developers · Oct 1, 2019

成为英雄:用 Quire API 打造你自己的应用

AI 翻译
· 查看英文版

Quire API

最后更新:2026 年 5 月 28 日

TL;DR:Quire OAuth 2.0 API 让你的应用能够代表用户操作其 Quire 账户,而无需存储他们的密码。你需要一个已注册的 OAuth 应用(客户端 ID、密钥、重定向 URL)、四步授权流程(配置、重定向、处理响应、用授权码换取令牌),以及刷新令牌循环——因为访问令牌一小时后就会过期。

构建一个能读取或修改用户 Quire 数据的应用,首先要做一个决定:如何在不接触用户密码的情况下完成身份验证?Quire API 通过 OAuth 2.0 给出了答案。本文将逐步介绍 OAuth 应用配置、四步授权流程、访问令牌与刷新循环,以及开发者首次构建时常踩的坑。

Quire OpenAPI 1.0.0 版本于 2019 年 10 月发布,至今保持稳定。通过 OAuth,用户授权你的应用访问其 Quire 内容(任务、项目、评论、分配、标签、截止日期),而你无需接触他们的凭据。用户随时可以撤销授权,且无需更改密码——这正是为什么在 OAuth 普及之前,存储密码的集成方式是一种安全反模式。

哪种 Quire 集成方式适合你的使用场景?

在接入 OAuth API 之前,先确认 API 是否真的是最合适的工具。2026 年 Quire 提供四种受支持的集成方式,各自解决不同的问题。

如果你需要… 使用 原因
在自己的应用中代表用户读取或修改 Quire 数据 Quire OAuth API(本文) 用户授权、完整 CRUD 访问、无需轮询
响应 Quire 中的事件(任务创建、状态变更、评论添加) Quire Webhooks 推送驱动、无轮询开销、配置轻量
将 Quire 连接到 Claude 或其他 AI 代理 Quire MCP 服务器 LLM 工具的标准协议,内置预构建服务器
将 Quire 数据接入自动化或 BI 工作流 OAuth API 配合 n8nPower BI 成熟的数据管道,减少自定义代码

如果你正在构建典型的应用集成(移动应用、Web 仪表板、同步服务),OAuth API 就是你需要的。本文其余部分默认你走的是这条路。

如何为 Quire API 配置 OAuth 应用?

使用 Quire API 之前,你需要先创建一个 OAuth 应用。

创建你的 Quire OAuth 应用

创建应用需要先登录你的 Quire 账户。

  1. 前往 Quire 开发者应用控制台,点击 Create new app 按钮。 Quire developer app console

  2. 选择应用所属的 Quire 组织,该组织的成员可以查看和编辑所有属于该组织的应用。 Quire 应用组织

  3. 填写应用名称和重定向 URL,重定向 URL 的作用我们稍后会介绍。现在可以先填写以下 URL:

    http://localhost:3000/callback

  4. 点击 Create new app 按钮,新创建的 OAuth 应用将显示在开发者控制台页面上,你可以在此进一步配置。 Quire 应用列表

总结一下,你需要记录以下三项信息:

  • 开发客户端 ID: :wJoMEodI4fSSR54pfNwIuIzLnaJ
  • 开发客户端密钥: eb8faf4nyd1wbeconw060e9ejui8zg6w8p1hyoex
  • 回调 URL: http://localhost:3000/callback

Quire 应用凭据

如何搭建 Quire API 的开发环境?

第一步:配置你的应用

在应用中存储配置信息。

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 进行授权

生成授权 URL,将用户重定向到 Quire 的 OAuth 端点。用户登录 Quire 后,将看到一个页面,可在此授权你的应用访问其内容。

示例 URL:

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)攻击。你应该随机生成该字符串,它将在第三步原封不动地回传给你的应用,应用需要验证该值。虽然此参数是可选的,但我们强烈建议包含它。

示例 URL:

https://quire.io/oauth?client_id=your-client-ID&redirect_uri=your-redirect-uri&state=lpcl9v94z

第三步:处理 OAuth 2.0 服务器响应

OAuth 2.0 服务器会通过 redirect_uri 中指定的 URL 响应你的应用访问请求。

如果用户批准了访问请求,响应中将包含一个授权码。如果用户拒绝,响应中将包含错误信息。返回给 Web 服务器的授权码或错误信息会出现在查询字符串中,如下所示:

错误响应:

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 如果你在第二步中指定了 redirect_uri,则此参数为必填项,且值必须与第二步中使用的完全一致。

请求访问令牌的示例:

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 都需要用到它。

如何使用 Quire 访问令牌调用 API?

你的应用现在已经拥有访问令牌,可以代表用户发起 API 调用了。

调用 API

在请求头中以 bearer token 的形式传入访问令牌来发起 API 调用。

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"
}

如何刷新已过期的 Quire API 访问令牌?

访问令牌本身就是为短期使用而设计的,这是 OAuth 2.0 的重要安全机制。使用授权码授权流程时,访问令牌默认有效期为一小时。

访问令牌过期后,将返回 HTTP 401 错误:

{ 
  code: 401, 
  message: 'Invalid or expired token.' 
}

Your application will need to refresh the 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 时最常犯哪些错误?

观察各团队基于 Quire API 的开发过程,同样的五个问题反复出现。这些问题都不难发现,也完全可以避免。

1. 将客户端密钥存储在客户端代码中。 客户端密钥本就是机密信息。如果它出现在移动应用的二进制文件或浏览器打包文件中,任何人都可以提取并冒充你的应用。密钥只应存在于你控制的服务器上。如果你的应用是纯客户端应用(单页应用、移动应用),应使用 OAuth 2.0 PKCE 流程,而不是内嵌密钥。

2. 忘记验证 state 参数。 state 参数的存在是为了防止 CSRF 攻击。如果你在回调时跳过验证,就留下了一个漏洞,恶意网站可以利用它将 Quire 账户静默关联到攻击者的应用会话。每次请求都要生成新的 state,将其存储在会话中,并拒绝任何返回 state 不匹配的回调。

3. 将访问令牌视为永久有效。 访问令牌一小时后过期。那些存储令牌后从不刷新的应用,第一天运行正常,第二天就会悄然失效。在上线之前就构建好刷新令牌循环,不要等用户投诉后再亡羊补牢。

4. 通过轮询 API 获取变更。 轮询会消耗频率限制、增加延迟、耗尽电量。如果你需要响应 Quire 中的变更,请改用 webhooks。Webhook 会即时将事件推送给你,原本需要发起的 API 调用根本不需要发生。

5. 跳过重定向 URL 白名单配置。 每个 OAuth 应用注册时都要填写允许的重定向 URL 列表。如果你使用通配符或配置不够精确,攻击者就可以将自己的回调注册为你的重定向目标,从而截获授权码。只添加你的应用实际使用的精确 URL。

如果你是第一次对接 API,最快的学习方式是 fork 一个现有集成(比如 n8n 连接器)并研究它如何处理身份验证、刷新和错误状态。

什么情况下 Quire API 不是最佳选择?

以下三种场景应该选择其他集成方式。

  • 你只需要响应事件,而不需要查询状态。 Webhooks 更简单、基于推送,且只读事件订阅不需要用户授权。如果你的应用的职责是"有事发生时通知我",用 webhook,不用 API。
  • 你正在构建 Claude 或 LLM 代理集成。 Quire MCP 服务器才是正确的选择。它处理身份验证、提供标准模式,意味着你根本不需要自己编写 OAuth 代码。MCP 专为此场景设计;用 OAuth API 自己实现只是用更多工作换来相同的结果。
  • 你只需要一次性数据导出。 如果你只需要提取一次项目数据用于分析或备份,n8n 集成或手动 CSV 导出能为你节省一周的开发时间。

如果以上都不适用,OAuth API 就是你的工具。

常见问题

Quire API 需要付费计划吗?

不需要。Quire API 在所有计划中均可使用,包括 Free 层。所有计划均有频率限制;请查阅 API 文档了解当前每个应用的具体限制。

Quire API 支持哪些编程语言?

该 API 基于 HTTP,使用 JSON 格式的请求和响应体,因此任何支持 HTTP 客户端和 JSON 解析器的语言都可以使用。本文示例使用 JavaScript,但相同的流程同样适用于 Python、Go、Ruby、PHP 及其他任何语言。目前没有官方客户端库;常见的做法是在你所用语言的 HTTP 客户端上封装一个薄层。

Quire 访问令牌的有效期是多长?

访问令牌默认在一小时后过期。刷新令牌的有效期更长,可用于在不重新提示用户的情况下获取新的访问令牌。从第一天起就将刷新令牌循环内置到你的应用中。

我可以将 Quire API 用于只读访问吗?

可以。OAuth 作用域允许你只申请应用所需的权限。如果你的应用只读取任务,则申请读取作用域即可。Quire 用户在授权页面上会看到所请求的作用域,如果权限申请过多,他们可以拒绝,因此过度申请权限会影响转化率。

Quire API 和 Quire MCP 服务器有什么区别?

API 是一个通用 REST 接口,适用于任何需要代表用户读取或修改 Quire 数据的应用。MCP 服务器专为 Claude 和其他 LLM 代理设计:它处理身份验证、提供标准工具模式,意味着你无需自己编写 OAuth 代码。传统应用集成使用 API;LLM 代理集成使用 MCP。

接下来怎么做?

以上就是 Quire API 的完整 OAuth 2.0 流程:OAuth 应用配置、四步授权、访问令牌使用,以及刷新循环。开发者最常遇到的情况是——集成上线时运行正常,两天后突然失效——根本原因就是把刷新循环当成"以后再说"的事,而不是从第一天起就内置进去。

前往 Quire 开发者应用控制台开始,或阅读完整的 API 参考文档。如果你根本不想写 OAuth 代码,Quire MCP 服务器会为你处理身份验证,是 LLM 代理集成的最佳选择。对于事件驱动的集成,webhooks 通常比大多数首次 API 集成最终依赖的轮询模式更合适。

Jimmy Shiau
Software Engineer