使用 Airforce 登录
让你的用户授权你的应用访问他们的 Api.Airforce 账户。带 PKCE 的标准 OAuth 2.0 Authorization Code 流程。
适用对象
你正在构建一个应用(playground、代理、移动客户端、…),希望你的用户接入他们的 Airforce 账户,以便通过你的 UI 运行聊天或图像生成,而不必把原始 API 密钥分享给你。使用此流程。
你会得到一个不透明的 access_token (24h TTL),其作用域限定为你的应用请求且用户批准的范围。将其作为 Bearer 头用于 /v1/* 端点或 /oauth/userinfo.
1. 获取 client_id + client_secret
Phase 1 是管理员管理的注册。请联系我们并提供:
- 应用名称(在同意屏幕上展示给你的用户)
- 一句话描述
- 主页 URL(可选,显示在同意屏幕)
- 方形 logo URL(可选)
- 一个或多个精确的 redirect_uri(仅 https://,除开发用 http://localhost)
- 你需要哪些 scope(见下文)
我们将回传给你 client_id 和一个一次性的 client_secret. 把 secret 保存在服务端 — 如果你是纯 SPA / 原生应用且没有后端,可以跳过 secret,只依赖 PKCE。
2. Scope
| Scope | 授予的权限 |
|---|---|
| profile | 通过 /oauth/userinfo 读取 user 对象(id、username、plan、已验证时的关联邮箱)。 |
| chat | POST /v1/chat/completions, /v1/messages, /v1/messages/count_tokens, /v1/responses. |
| images | POST /v1/images/generations. |
| keys:read | 保留 — 列出用户的 Airforce API 密钥(Phase 2)。 |
| keys:write (敏感) | 保留 — 创建 + 撤销用户的 Airforce API 密钥(Phase 2)。敏感 scope。 |
多个 scope 在 scope 查询参数中以空格分隔: scope=profile chat images.
3. 流程
3.1 生成 PKCE 对
在客户端,重定向到 /oauth/authorize 之前,生成一个随机 verifier 和匹配的 SHA-256 challenge。
// In your app, before redirecting to /oauth/authorize:
const verifier = randomString(64); // 43..128 chars [A-Z][a-z][0-9]-._~
const challenge = base64UrlNoPad(sha256(verifier));
sessionStorage.setItem('airforce_pkce_verifier', verifier);3.2 重定向到 /oauth/authorize
构造 authorize URL 并把用户送过去。他会看到我们的同意屏幕,做出决定,然后被重定向回你这里。
https://api.airforce/oauth/authorize?
response_type=code
&client_id=airforce_xxxxxxxxxxxxxxxxxxxxxxxxx
&redirect_uri=https://your.app/oauth/callback
&scope=profile chat
&state=<random opaque>
&code_challenge=<base64url(sha256(verifier))>
&code_challenge_method=S256用户到达我们的同意屏幕,登录(如果尚未登录),然后批准或拒绝。我们会重定向回你的 redirect_uri 并附上短期的 ?code=… (批准时), ?error=access_denied (拒绝时)。你原始的 state 会被回传 — 请验证是否匹配。
3.3 用 code 换取 access_token
从你的后端,用 code(加上 PKCE verifier)换取一个 access token。
curl -X POST https://api.airforce/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "$CLIENT_ID:$CLIENT_SECRET" \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "code=$CODE" \
--data-urlencode "redirect_uri=https://your.app/oauth/callback" \
--data-urlencode "code_verifier=$VERIFIER"响应(24h TTL):
{
"access_token": "airf_oat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"token_type": "Bearer",
"expires_in": 86400,
"scope": "profile chat"
}3.4 使用 token
调用 userinfo 端点或所授予 scope 允许的任何 /v1/* 路由:
# Profile lookup
curl https://api.airforce/oauth/userinfo \
-H "Authorization: Bearer $ACCESS_TOKEN"
# Chat (requires scope=chat)
curl https://api.airforce/v1/chat/completions \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Hi"}]}'/oauth/userinfo 响应
{
"id": "user-uuid",
"username": "foo",
"plan": "free",
"is_admin": false,
"email": "[email protected]",
"email_verified": true,
"github_email": "[email protected]",
"discord_username": "foo#1234"
}诸如 email, github_email, discord_username 之类的字段,只有当用户确实已验证 / 关联时才会出现。请同时考虑存在与不存在的情况。
撤销 token
当用户从你的应用登出时,撤销 token 以避免它在后台继续扣费:
curl -X POST https://api.airforce/oauth/revoke \
--data-urlencode "token=$ACCESS_TOKEN"RFC 7009。无论 token 是否存在,始终返回 200 (无 oracle)。
安全注意事项
- PKCE 对公共客户端是强制的 (没有服务端 client_secret)。我们仅接受 S256 —
code_challenge_method=plain会被拒绝。 - redirect_uri 为精确匹配。 没有前缀 / 通配符匹配。如果你需要多个环境,请为每个环境注册一个 URI。
- Token 拥有 24h TTL 且暂时没有 refresh token — 过期时让用户重新走一遍
/oauth/authorize。对于长期运行的代理,启动时提示并把 token 存到安全存储。 - 不要把 client_secret 存放在客户端代码中。 如果你的应用是纯浏览器 SPA 或原生客户端,请在无服务器情况下注册并依赖 PKCE。
- 用户可随时从他们的 dashboard → Apps 标签撤销你的应用。通过重新运行 OAuth 流程来处理 401。
- Phase 1 覆盖范围: OAuth bearer token 适用于
/v1/chat/completions,/v1/messages,/v1/messages/count_tokens,/v1/responses,/v1/images/generations, 和/oauth/userinfo. 音频、视频、语音和 character 端点在 Phase 1 仍需要常规的 Airforce API 密钥。
注册
发送邮件至 [email protected] 或在 Discord 上联系我们,并附上上面列出的注册详情。我们将在数小时内把你的凭证发回。
设置卡住,或想要免费密钥?来我们的 Discord 问问社区吧。
加入我们的 Discord