认证 API¶
所有认证接口位于 /auth 路径前缀下,负责用户注册、登录、OAuth、会话管理和个人资料更新。
接口列表¶
POST /auth/register¶
创建新用户账户。
请求体:
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
email |
string | 是 | 有效的邮箱地址 |
username |
string | 是 | 唯一的用户名 |
password |
string | 是 | 至少 8 个字符 |
响应: 201 Created
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJl...",
"user": {
"id": "01912345-6789-7abc-def0-123456789abc",
"email": "user@example.com",
"username": "inkuser",
"createdAt": "2026-01-15T10:30:00Z",
"updatedAt": "2026-01-15T10:30:00Z"
}
}
错误:
| 状态码 | 原因 |
|---|---|
400 |
字段缺失或格式无效 |
409 |
邮箱或用户名已被占用 |
POST /auth/login¶
使用邮箱或用户名加密码进行认证。
请求体:
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
identifier |
string | 是 | 邮箱地址或用户名 |
password |
string | 是 | 账户密码 |
响应: 200 OK
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJl...",
"user": {
"id": "01912345-6789-7abc-def0-123456789abc",
"email": "user@example.com",
"username": "inkuser",
"createdAt": "2026-01-15T10:30:00Z",
"updatedAt": "2026-01-15T10:30:00Z"
}
}
错误:
| 状态码 | 原因 |
|---|---|
400 |
字段缺失 |
401 |
凭据无效 |
POST /auth/refresh¶
使用有效的刷新令牌换取新的令牌对。旧的刷新令牌将被废止。
请求体:
响应: 200 OK
错误:
| 状态码 | 原因 |
|---|---|
401 |
刷新令牌无效、已过期或已被使用 |
令牌轮换
刷新令牌为一次性使用。每次调用此接口都会废止之前的刷新令牌并返回新的令牌对。如果刷新令牌被重复使用,作为安全措施,该用户的所有会话可能会被撤销。
POST /auth/logout¶
:material-lock: 需要认证
撤销提供的刷新令牌,结束会话。
请求头:
请求体:
响应: 200 OK
错误:
| 状态码 | 原因 |
|---|---|
401 |
访问令牌缺失或无效 |
GET /auth/me¶
:material-lock: 需要认证
获取当前认证用户的个人资料,包括关联的 OAuth 账户和订阅状态。
请求头:
响应: 200 OK
{
"id": "01912345-6789-7abc-def0-123456789abc",
"email": "user@example.com",
"username": "inkuser",
"createdAt": "2026-01-15T10:30:00Z",
"updatedAt": "2026-01-15T10:30:00Z",
"oauthAccounts": [
{
"provider": "google",
"providerUserId": "117382948271639",
"email": "user@gmail.com",
"linkedAt": "2026-01-20T14:00:00Z"
}
],
"subscription": {
"status": "active",
"plan": "pro",
"interval": "monthly",
"currentPeriodEnd": "2026-02-15T10:30:00Z",
"cancelAtPeriodEnd": false
}
}
提示
如果用户从未订阅过,subscription 字段为 null。
错误:
| 状态码 | 原因 |
|---|---|
401 |
访问令牌缺失或无效 |
PUT /auth/me¶
:material-lock: 需要认证
更新当前认证用户的个人资料。所有字段均为可选 --- 只需包含你要修改的字段。
请求头:
请求体:
{
"username": "newusername",
"password": "newSecurePassword456",
"currentPassword": "securePassword123"
}
| 字段 | 类型 | 必填 | 描述 |
|---|---|---|---|
username |
string | 否 | 新用户名 |
password |
string | 否 | 新密码(至少 8 个字符) |
currentPassword |
string | 条件必填 | 修改密码时必须提供当前密码 |
响应: 200 OK
{
"id": "01912345-6789-7abc-def0-123456789abc",
"email": "user@example.com",
"username": "newusername",
"createdAt": "2026-01-15T10:30:00Z",
"updatedAt": "2026-01-16T08:00:00Z"
}
错误:
| 状态码 | 原因 |
|---|---|
400 |
字段无效或修改密码时未提供 currentPassword |
401 |
访问令牌缺失或无效 |
409 |
用户名已被占用 |
GET /auth/sessions¶
:material-lock: 需要认证
列出当前认证用户的所有活跃会话。
请求头:
响应: 200 OK
[
{
"id": "01912345-0000-7abc-def0-000000000001",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
"ip": "192.168.1.100",
"createdAt": "2026-01-15T10:30:00Z",
"lastUsedAt": "2026-01-16T08:00:00Z"
},
{
"id": "01912345-0000-7abc-def0-000000000002",
"userAgent": "InkletDesktop/1.0",
"ip": "10.0.0.50",
"createdAt": "2026-01-14T09:00:00Z",
"lastUsedAt": "2026-01-15T22:00:00Z"
}
]
错误:
| 状态码 | 原因 |
|---|---|
401 |
访问令牌缺失或无效 |
DELETE /auth/sessions/{id}¶
:material-lock: 需要认证
通过 ID 撤销指定会话。这将废止与该会话关联的刷新令牌。
路径参数:
| 参数 | 描述 |
|---|---|
id |
会话 UUID |
请求头:
响应: 200 OK
错误:
| 状态码 | 原因 |
|---|---|
401 |
访问令牌缺失或无效 |
404 |
会话未找到或不属于当前用户 |
OAuth 接口¶
Inklet 支持 Google 登录和 Apple 登录。OAuth 流程使用服务端重定向。
GET /auth/oauth/google¶
发起 Google OAuth 登录。client 查询参数决定使用哪个重定向 URI。
查询参数:
| 参数 | 可选值 | 描述 |
|---|---|---|
client |
web, desktop, ios |
发起登录流程的客户端平台 |
示例:
响应: 302 Found --- 重定向至 Google 的 OAuth 授权页面。
GET /auth/oauth/google/callback¶
处理来自 Google 的 OAuth 回调。此接口不由客户端直接调用 --- 用户授权后由 Google 重定向至此。
行为:
- 如果该 Google 邮箱尚未注册,则创建新账户
- 如果邮箱匹配已有用户,则关联 Google 账户
- 通过重定向返回令牌(令牌作为查询参数或 fragment,取决于客户端类型)
GET /auth/oauth/apple¶
发起 Apple OAuth 登录。
查询参数:
| 参数 | 可选值 | 描述 |
|---|---|---|
client |
web, desktop, ios |
发起登录流程的客户端平台 |
示例:
响应: 302 Found --- 重定向至 Apple 的 OAuth 授权页面。
POST /auth/oauth/apple/callback¶
处理来自 Apple 的 OAuth 回调。Apple 使用 form_post 响应模式,因此此接口接收的是包含表单编码数据的 POST 请求,而非查询参数。
Apple OAuth 的不同之处
与 Google 不同,Apple 以 POST 请求发送回调,请求体为 application/x-www-form-urlencoded 格式。Apple 还仅在首次授权时提供用户姓名 --- 后续登录只包含邮箱。
行为:
- 如果该 Apple 邮箱尚未注册,则创建新账户
- 如果邮箱匹配已有用户,则关联 Apple 账户
- 通过重定向返回令牌