跳到主要内容

远程管理 API 参考

HeartbeatSocks 内置 REST API 服务,用于远程管理 SOCKS5 账号和查询用户信息。API 兼容 CCProxy ProxyAccount_Controller 接口规范。

总览

┌─────────────────────────────────────────────────────────────────┐
│ 远程管理 API 架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 客户端请求 ──▶ IP 白名单检查 ──▶ Basic Auth 认证 ──▶ 路由分发 │
│ │ │ │ │
│ 拒绝 403 拒绝 401 端点处理 │
│ │ │
│ ┌───────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ /ProxyAccount │ │
│ │ ├── GET /GetProxyAccountList 获取所有账号 │ │
│ │ ├── GET /GetProxyAccountByID 获取指定账号 │ │
│ │ ├── POST /AddProxyAccount 添加账号 │ │
│ │ ├── POST /UpdateProxyAccount 更新账号 │ │
│ │ ├── POST /DeleteProxyAccount 删除账号(含级联删除) │ │
│ │ └── GET /GetCurrentUser 获取当前用户(免认证) │ │
│ │ │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ 技术栈: ASP.NET Core Minimal API + Kestrel │
│ 数据格式: JSON │
│ 认证方式: HTTP Basic Authentication │
│ │
└─────────────────────────────────────────────────────────────────┘

基础信息

Base URL

http://{绑定IP}:{端口}

默认: http://localhost:8080

认证方式

API 使用 HTTP Basic Authentication,需要在请求的 Authorization Header 中携带 Base64 编码的管理员凭证。

Authorization: Basic {base64(username:password)}

示例(用户名 admin,密码 123456):

Authorization: Basic YWRtaW46MTIzNDU2
特殊端点

/ProxyAccount/GetCurrentUser 端点 不需要 Basic Auth 认证,它通过 X-Socks5-Username HTTP Header 识别用户身份。

安全机制

机制说明
IP 白名单配置后仅允许白名单中的 IP 访问,支持通配符(如 192.168.1.*
Basic AuthGetCurrentUser 外所有端点都需要管理员认证
密码哈希管理员密码和账号密码均以 SHA256 哈希存储
暴力破解防护认证失败时服务端延迟响应(500-1500ms 随机)
内网限制GetCurrentUser 仅允许本地/内网 IP 访问

请求/响应格式

  • Content-Type: application/json
  • 编码: UTF-8
  • 日期格式: ISO 8601(如 2025-01-01T00:00:00
  • ID 格式: Guid(兼容 CCProxy,内部通过 GuidHelper 与 int ID 互转)

端点详情

1. 获取所有账号

获取系统中所有 SOCKS5 账号列表,包含每个账号在数据池中的统计信息。

GET /ProxyAccount/GetProxyAccountList

认证: 需要 Basic Auth

请求参数: 无

响应: 200 OK

[
{
"AID": "00000000-0000-0000-0000-000000000001",
"Username": "player1",
"IsEnabled": true,
"Remarks": "测试账号",
"CreatedAt": "2025-01-15T08:30:00",
"LastLoginAt": "2025-06-01T14:22:33",
"ExpiresAt": null,
"DataCount": 152,
"LatestGameId": "A1B2C3D4E5"
},
{
"AID": "00000000-0000-0000-0000-000000000002",
"Username": "player2",
"IsEnabled": false,
"Remarks": "已停用",
"CreatedAt": "2025-02-20T10:00:00",
"LastLoginAt": "2025-05-15T09:10:00",
"ExpiresAt": "2025-12-31T23:59:59",
"DataCount": 0,
"LatestGameId": null
}
]

响应字段:

字段类型说明
AIDGuid账号唯一标识(CCProxy 兼容格式)
Usernamestring用户名
IsEnabledbool是否启用
Remarksstring?备注信息
CreatedAtDateTime创建时间
LastLoginAtDateTime?最后登录时间(未登录则为 null)
ExpiresAtDateTime?过期时间(null 表示永不过期)
DataCountint该账号在数据池中的心跳数据条数
LatestGameIdstring?该账号最近采集的 GameID

错误响应:

状态码说明
401 Unauthorized认证失败
403 ForbiddenIP 不在白名单中
500 Internal Server Error服务器内部错误

2. 获取指定账号

通过账号 ID 获取单个账号的详细信息和数据池统计。

GET /ProxyAccount/GetProxyAccountByID?AID={guid}

认证: 需要 Basic Auth

查询参数:

参数类型必填说明
AIDGuid账号唯一标识

请求示例:

GET /ProxyAccount/GetProxyAccountByID?AID=00000000-0000-0000-0000-000000000001

响应: 200 OK

{
"AID": "00000000-0000-0000-0000-000000000001",
"Username": "player1",
"IsEnabled": true,
"Remarks": "测试账号",
"CreatedAt": "2025-01-15T08:30:00",
"LastLoginAt": "2025-06-01T14:22:33",
"ExpiresAt": null,
"DataCount": 152,
"LatestGameId": "A1B2C3D4E5"
}

错误响应:

状态码说明
400 Bad Request无效的账号 ID 格式
404 Not Found账号不存在

3. 添加账号

创建新的 SOCKS5 代理账号。

POST /ProxyAccount/AddProxyAccount

认证: 需要 Basic Auth

请求体:

{
"Username": "new_player",
"Password": "my_secure_password",
"IsEnabled": true,
"Remarks": "新用户",
"ExpiresAt": "2026-12-31T23:59:59"
}

请求字段:

字段类型必填默认值说明
Usernamestring用户名(必须唯一)
Passwordstring密码(明文传输,服务端以 SHA256 哈希存储)
IsEnabledbooltrue是否启用
Remarksstring?null备注信息
ExpiresAtDateTime?null过期时间(null = 永不过期)

成功响应: 200 OK

"添加账号成功"

错误响应:

状态码说明
400 Bad Request用户名或密码为空、用户名已存在

业务规则:

  • 用户名不能为空,且必须唯一
  • 密码不能为空
  • 密码自动使用 SHA256 哈希后存储
  • 创建时间自动设为当前 UTC 时间

4. 更新账号

修改已有账号的信息。

POST /ProxyAccount/UpdateProxyAccount

认证: 需要 Basic Auth

注意

此端点使用 POST 而非 PUT,以兼容 CCProxy API 规范。

请求体:

{
"AID": "00000000-0000-0000-0000-000000000001",
"Password": "new_password",
"IsEnabled": true,
"Remarks": "更新后的备注",
"ExpiresAt": null
}

请求字段:

字段类型必填说明
AIDGuid要更新的账号 ID
Passwordstring新密码(留空或不填则不修改密码)
IsEnabledbool是否启用
Remarksstring?备注
ExpiresAtDateTime?过期时间

成功响应: 200 OK

"更新账号成功"

错误响应:

状态码说明
400 Bad Request账号 ID 为空、无效的 ID 格式、账号不存在

业务规则:

  • Password 为空或仅包含空白字符时不修改密码
  • IsEnabledRemarksExpiresAt 总是会被更新(即使未提供也会使用默认值)

5. 删除账号

删除指定账号及其所有关联数据。

POST /ProxyAccount/DeleteProxyAccount?AID={guid}

认证: 需要 Basic Auth

注意

此端点使用 POST 而非 DELETE,以兼容 CCProxy API 规范。

查询参数:

参数类型必填说明
AIDGuid要删除的账号 ID

请求示例:

POST /ProxyAccount/DeleteProxyAccount?AID=00000000-0000-0000-0000-000000000001

成功响应: 200 OK

"删除账号成功"

错误响应:

状态码说明
400 Bad Request无效的 ID 格式、账号不存在
级联删除

删除账号时会同时删除该账号在数据池中的所有心跳数据(包括内存和数据库中的数据)。此操作不可逆。

级联删除流程:

  1. 从数据库删除该用户名关联的所有心跳数据
  2. 从内存数据池中移除该用户名的所有数据
  3. 删除账号本身

6. 获取当前用户

通过 HTTP Header 中的用户名获取当前 SOCKS5 认证用户的信息。此端点专为客户端应用设计,用于查询自身账号状态。

GET /ProxyAccount/GetCurrentUser

认证: 不需要 Basic Auth(通过 HTTP Header 识别用户)

请求 Header:

Header必填说明
X-Socks5-UsernameSOCKS5 认证的用户名

请求示例:

GET /ProxyAccount/GetCurrentUser
X-Socks5-Username: player1

成功响应: 200 OK

{
"Username": "player1",
"IsEnabled": true,
"CreatedAt": "2025-01-15T08:30:00",
"LastLoginAt": "2025-06-01T14:22:33",
"ExpiresAt": null,
"IsExpired": false,
"DataCount": 152,
"LatestGameId": "A1B2C3D4E5"
}

响应字段:

字段类型说明
Usernamestring用户名
IsEnabledbool是否启用
CreatedAtDateTime创建时间
LastLoginAtDateTime?最后登录时间
ExpiresAtDateTime?过期时间(null = 永不过期)
IsExpiredbool当前是否已过期
DataCountint该用户在数据池中的心跳数据条数
LatestGameIdstring?最近采集的 GameID

错误响应:

状态码说明
401 Unauthorized缺少 X-Socks5-Username Header
403 Forbidden来源 IP 不是本地或内网地址
404 Not Found用户不存在

安全限制:

  • 仅允许以下 IP 范围访问:
    • 127.0.0.0/8(回环地址)
    • 10.0.0.0/8(A 类私有地址)
    • 172.16.0.0/12(B 类私有地址)
    • 192.168.0.0/16(C 类私有地址)
    • fc00::/7(IPv6 唯一本地地址)
    • fe80::/10(IPv6 链路本地地址)

端点总表

方法路径认证说明
GET/ProxyAccount/GetProxyAccountListBasic Auth获取所有账号列表(含数据池统计)
GET/ProxyAccount/GetProxyAccountByID?AID={guid}Basic Auth获取单个账号详情
POST/ProxyAccount/AddProxyAccountBasic Auth创建新账号
POST/ProxyAccount/UpdateProxyAccountBasic Auth更新账号信息
POST/ProxyAccount/DeleteProxyAccount?AID={guid}Basic Auth删除账号(含级联删除数据)
GET/ProxyAccount/GetCurrentUserHeader获取当前 SOCKS5 用户信息

使用示例

cURL

获取所有账号:

curl -u admin:password123 \
http://localhost:8080/ProxyAccount/GetProxyAccountList

添加账号:

curl -u admin:password123 \
-X POST \
-H "Content-Type: application/json" \
-d '{"Username":"player1","Password":"pass123","IsEnabled":true,"Remarks":"新用户"}' \
http://localhost:8080/ProxyAccount/AddProxyAccount

更新账号:

curl -u admin:password123 \
-X POST \
-H "Content-Type: application/json" \
-d '{"AID":"00000000-0000-0000-0000-000000000001","IsEnabled":false,"Remarks":"已停用"}' \
http://localhost:8080/ProxyAccount/UpdateProxyAccount

删除账号:

curl -u admin:password123 \
-X POST \
"http://localhost:8080/ProxyAccount/DeleteProxyAccount?AID=00000000-0000-0000-0000-000000000001"

获取当前用户(仅限本地/内网):

curl -H "X-Socks5-Username: player1" \
http://localhost:8080/ProxyAccount/GetCurrentUser

PowerShell

# 设置认证
$cred = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("admin:password123"))
$headers = @{ Authorization = "Basic $cred" }

# 获取所有账号
Invoke-RestMethod -Uri "http://localhost:8080/ProxyAccount/GetProxyAccountList" `
-Headers $headers

# 添加账号
$body = @{
Username = "player1"
Password = "pass123"
IsEnabled = $true
Remarks = "新用户"
} | ConvertTo-Json

Invoke-RestMethod -Uri "http://localhost:8080/ProxyAccount/AddProxyAccount" `
-Method Post -Headers $headers -ContentType "application/json" -Body $body

C# HttpClient

using var client = new HttpClient();

// 设置 Basic Auth
var credentials = Convert.ToBase64String(
Encoding.UTF8.GetBytes("admin:password123"));
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", credentials);

// 获取所有账号
var response = await client.GetAsync(
"http://localhost:8080/ProxyAccount/GetProxyAccountList");
var accounts = await response.Content
.ReadFromJsonAsync<List<AccountResponse>>();

// 添加账号
var request = new
{
Username = "player1",
Password = "pass123",
IsEnabled = true,
Remarks = "新用户"
};
await client.PostAsJsonAsync(
"http://localhost:8080/ProxyAccount/AddProxyAccount", request);

错误处理

通用 HTTP 状态码

状态码说明常见原因
200 OK操作成功
400 Bad Request请求参数错误缺少必填字段、ID 格式无效、用户名重复
401 Unauthorized认证失败未提供凭证、用户名或密码错误
403 Forbidden访问被拒绝IP 不在白名单中、外网访问受限端点
404 Not Found资源不存在账号 ID 不存在、用户名不存在
500 Internal Server Error服务器错误数据库异常、内部处理失败

错误响应格式

错误信息以纯字符串返回(兼容 CCProxy):

"用户名和密码不能为空"
"该用户名已存在"

IP 白名单配置

在「系统配置」页面的 IP 白名单字段中配置允许访问 API 的 IP 地址。

格式

多个 IP 用逗号分隔:

192.168.1.100, 192.168.1.101, 10.0.0.50

支持通配符

192.168.1.*     # 匹配 192.168.1.0/24 段
10.* # 匹配 10.0.0.0/8 段
* # 允许所有 IP(等同于不配置白名单)

注意事项

  • 白名单为空时,允许所有 IP 访问
  • 支持 IPv4 和 IPv6 地址
  • IPv4-mapped IPv6 地址(如 ::ffff:192.168.1.100)会自动转换为 IPv4 格式匹配
  • 配置变更后无需重启 API 服务,下次请求立即生效(使用内部缓存优化性能)