══════════════════════════════════════════════════════════ 项目云「删除接口」客户端对接文档 2026-09-24 · 适用服务端 v1.5.1 ══════════════════════════════════════════════════════════ 一、接口总览 ────────────────────────────── 删除接口是项目云 API 之一,与其他项目云接口共用同一套 鉴权方式(手机号 + 密码)。全部项目云接口: POST /api/proj/upload 上传项目 zip(覆盖式,≤2GB,每会员共 1GB) GET /api/proj/list 列出该手机号名下全部项目 GET /api/proj/download 下载项目 zip POST /api/proj/delete ★ 本文档:删除一个项目 项目云所有接口都有两种调用方式: · 方式 A:信封加密通道(推荐,与登录/注册同一套封装) · 方式 B:HTTPS 明文 JSON(与上传/下载同一套封装) 二、服务端实现说明(方式 B:HTTPS 明文) ────────────────────────────── 【请求】 POST https://服务器IP:端口/api/proj/delete Content-Type: application/json 请求体(JSON,UTF-8): { "手机号": "13800001111", "密码": "该会员的登录密码", "编号": "要删除的项目编号" } 【服务端处理流程】 1. 校验手机号+密码与 huiyuan.json 中会员记录匹配 (不匹配 → {ok:false, msg:"手机号或密码错误"}) 2. 编号经文件名安全化后拼出项目目录,并做防路径穿越校验 (拼接结果必须仍在 项目云 根目录之下) 3. 直接递归删除该项目的整个目录(项目.zip + meta.json) 4. 删除是不可恢复的物理删除 【响应】 成功: {"ok": true} 失败: {"ok": false, "msg": "失败原因"} 常见失败: "手机号或密码错误" 鉴权失败 "参数错误" 手机号或编号缺失 "该接口已迁移至加密通道,请升级客户端并使用 https://IP:端口 连接" 用了 http:// (必须 https) 三、服务端实现说明(方式 A:信封加密通道 /api/enc) ────────────────────────────── 删除接口与项目列表一起,同时注册在加密通道内 (ENC_ROUTES),客户端如果已经在用登录/注册的信封封装, 删除不需要单独再发明文请求,走同一封装即可。 【流程】 1. GET https://服务器IP:端口/api/pubkey → {"ok":true, "pubkey":"RSA公钥PEM", "keyfp":"指纹"} 2. 客户端随机生成 32 字节 AES-256 密钥 + 16 字节 IV 3. 业务 JSON(下述 inner)用 AES-256-CBC 加密 4. AES 密钥用 RSA-2048 OAEP(SHA-1) 封装 5. POST /api/enc,请求体: { "k": AES密钥的RSA-OAEP封装(base64), "iv": AES IV(hex), "data": 密文(base64), "mac": HMAC-SHA256(ts+'.'+nonce+'.'+iv+'.'+data) hex, "ts": 毫秒时间戳(±5分钟有效), "nonce":随机数(10分钟内不可重复) } 其中密文解开后是 inner: { "path": "/api/proj/delete", "body": { "手机号":"...", "密码":"...", "编号":"..." } } 6. 响应也是加密的:{"ok":true,"iv":..,"mac":..,"data":..} data 用同一 AES 密钥解开即 {"ok":true} 【注意】 · /api/enc 只在 HTTPS 端口提供,http 端口一律返回 TLS_REQUIRED 迁移提示 · 防重放:同一 nonce 10 分钟内第二次提交会被拒绝 · HMAC 校验失败 = 数据被篡改,服务端直接拒绝 四、端口与地址 ────────────────────────────── · 客户端所有接口一律走 HTTPS: https://飞牛主机IP:HTTPS端口 · HTTPS 端口 = 网页端口 + 1(默认网页 12701 → HTTPS 12702) · 证书是自签的,客户端需忽略证书校验 (.NET: ServicePointManager.ServerCertificateValidationCallback 返回 true;或比对 /api/pubkey 的 keyfp 指纹) · 手机号 11 位数字;密码即会员登录密码(与 /api/login 相同) 五、调用时序建议 ────────────────────────────── 1. (首次)GET /api/pubkey 取公钥与指纹,指纹可展示给 用户核对,防中间人 2. 客户端本地登录缓存手机号+密码(或调用 /api/login 验证) 3. GET /api/proj/list 拿项目编号列表(编号即删除参数) 4. 用户确认要删除后,POST /api/proj/delete 传编号 5. 依返回 ok 刷新本地项目列表 六、删除的边界行为 ────────────────────────────── · 删除的单位是"项目编号":一个编号对应项目云里一个 目录(项目.zip + meta.json),整体删除 · 编号不存在时不会报错,同样返回 {ok:true}(幂等) · 不提供批量删除参数,多个项目由客户端循环逐条调用 (每条之间建议留 200ms 间隔,避免触发限速) · 登录/管理接口按 IP 限速(1 分钟内失败≥10 次锁 60 秒), 删除接口的鉴权失败不计入限速计数,无请求频率限制 七、明文调用示例(方式 B,C#) ────────────────────────────── // 忽略自签证书 ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, err) => true; var url = "https://192.168.1.10:12702/api/proj/delete"; var body = "{\"手机号\":\"13800001111\",\"密码\":\"123456\",\"编号\":\"XM20260924001\"}"; var req = (HttpWebRequest)WebRequest.Create(url); req.Method = "POST"; req.ContentType = "application/json"; var bytes = Encoding.UTF8.GetBytes(body); using (var st = req.GetRequestStream()) st.Write(bytes, 0, bytes.Length); try { using (var resp = (HttpWebResponse)req.GetResponse()) using (var rs = new StreamReader(resp.GetResponseStream(), Encoding.UTF8)) { Console.WriteLine(rs.ReadToEnd()); // 成功输出: {"ok":true} } } catch (WebException ex) { using (var rs = new StreamReader(ex.Response.GetResponseStream(), Encoding.UTF8)) Console.WriteLine(rs.ReadToEnd()); // {"ok":false,"msg":"..."} } 八、错误码速查 ────────────────────────────── {"ok":true} 删除成功(含"项目本来就不存在") 手机号或密码错误 鉴权失败 参数错误 手机号或编号为空 TLS_REQUIRED / 该接口已迁移… 用了 http,改 https 时间戳超出允许窗口(±5分钟) 信封模式 ts 偏差过大,校时 重复的请求(疑似抓包重放) 信封模式 nonce 重复 九、与原「客户端对接示例.cs」的关系 ────────────────────────────── 原示例文件(项目根目录 客户端对接示例.cs)覆盖登录/注册/ 信封加密的完整实现。本文档只补充"删除"这一个接口: 两种调用方式与列表/上传/下载完全同构,把示例中已有的 信封 path 换成 /api/proj/delete、body 换成 {手机号,密码,编号} 即可,无任何新协议。