FileGator v7.16.8 API 使用详解
FileGator v7.16.8 HTTP JSON API 详解:会话+CSRF 双认证约定、21 条路由端点总览、认证/文件/上传下载/打包批量下载/用户管理五域逐条实测调用与回显,含 v7.16.8 返回值缺陷与排障实录。
FileGator v7.16.8 API 使用详解
目标:讲清 FileGator v7.16.8 的 HTTP JSON API——会话与 CSRF 双认证约定、全部 21 条路由端点总览、核心域(认证/文件/上传下载/打包/用户管理)的逐条实测调用与回显,以及踩坑清单。全部请求与回显均在 2026-10-30 于官方镜像部署栈上实测照抄;API 无独立 Key 体系,调用方式与前端页面完全同构。
一、环境信息
- 实测对象:FileGator v7.16.8(官方镜像
filegator/filegator:v7.16.8,API 版本经GET /?r=/getconfig返回app_version: 7.16.8确认) - 实测入口:
http://127.0.0.1:8149(部署见 《FileGator v7.16.8 Docker Compose 部署指南》) - 测试账号:
admin/q1w2e3r4(改密后的管理员)、dev1/q1w2e3r4(实测创建的 user 角色账号) - 路由表版本:官方仓库
backend/Controllers/routes.php(2026-10-30 实查,21 条路由) - 工具:curl(session cookie + CSRF 头双携带)
二、前置条件
- FileGator 栈已按部署指南拉起,且 admin 已改密(
q1w2e3r4)。 - API 无 OpenAPI 文档、无独立 API Key——认证体系就是浏览器页面用的 PHP 会话,脚本化调用模拟浏览器即可。
- 需理解两个前置机制(本文实测结论):
- 路由形态:所有端点走查询参数
?r=/端点(配置query_param默认 'r')。直接访问/login等路径返回 Apache 404(官方镜像无 URL 重写规则,实测确认)。 - CSRF 防护:GET/HEAD/OPTIONS 请求的响应头下发
X-CSRF-Token;所有 POST 请求必须回带同名请求头,否则返回 HTTP 200 + 空响应体(应用日志记Csrf token not valid)。
- 路由形态:所有端点走查询参数
三、认证与调用约定
3.1 双件套获取流程
每次脚本会话的标准开场(三步):
# 1) 匿名 GET:建立会话(cookie)+ 拿 CSRF token(响应头)
TOKEN=$(curl -s -i -c cookies.txt "http://127.0.0.1:8149/?r=/getuser" | grep -i 'x-csrf-token' | tr -d '\r' | awk '{print $2}')
echo "$TOKEN"
实测回显(token 形态为三段点分串):
2002eab0f4686bd477034893e1cf4.PDvbVu-2KR3H3KRzN8Szyc1S5ySToSdLYp2DF1oBF68.X2nvNK7ScGq1sO4gUYXem4YLgmjrmBE-OtjoIwVkdPlwWqpv1vdhcpftww
# 2) 登录(带 cookie + token)
curl -s -b cookies.txt -c cookies.txt -X POST "http://127.0.0.1:8149/?r=/login" \
-H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
-d '{"username":"admin","password":"q1w2e3r4"}'
实测回显:
{"data":{"role":"admin","permissions":["read","write","upload","download","batchdownload","zip","chmod"],"homedir":"\/","username":"admin","name":"Admin"}}
# 3) 登录后必须重新 GET 一次拿新 token(登录会迁移会话 ID,旧 token 失效——实测踩坑)
TOKEN=$(curl -s -i -b cookies.txt -c cookies.txt "http://127.0.0.1:8149/?r=/getuser" | grep -i 'x-csrf-token' | tr -d '\r' | awk '{print $2}')
3.2 响应约定
- 成功:
{"data": <结果>}(列表/对象/字符串按端点不同)。 - 业务失败:
{"data":"Failed"}/{"data":"Login failed, please try again"}等(注意 v7.16.8 部分端点 Failed 但操作实际成功,见第七章)。 - 参数校验失败:HTTP 422 +
{"<字段>":"This field is required"}形态。 - 认证过期:重定向回
/(HTML)或返回 guest 角色对象。 - 全部业务端点要求 JSON 请求体(
Content-Type: application/json);上传端点例外用 multipart。
四、端点总览(21 条路由全集)
按官方路由表(routes.php 2026-10-30 实查)整理,permissions 列为通过该端点所需的权限位:
| 方法 | 端点(?r= 后) | 作用 | 允许角色 | 需要权限 |
|---|---|---|---|---|
| GET | / | 前端页面 | guest/user/admin | - |
| POST | /login | 登录 | guest | - |
| POST | /logout | 登出 | 三角色 | - |
| GET | /getuser | 当前用户信息 | 三角色 | - |
| POST | /changepassword | 改自己密码 | user/admin | - |
| GET | /getconfig | 前端配置 | 三角色 | - |
| POST | /changedir | 切换当前目录(会话态) | 三角色 | read |
| POST | /getdir | 列目录 | 三角色 | read |
| POST | /copyitems | 复制 | 三角色 | read+write |
| POST | /moveitems | 移动 | 三角色 | read+write |
| POST | /renameitem | 重命名 | 三角色 | read+write |
| POST | /zipitems | 打包 zip | 三角色 | read+write+zip |
| POST | /unzipitem | 解压 | 三角色 | read+write+zip |
| POST | /chmoditems | 改权限位 | 三角色 | read+write+chmod |
| POST | /deleteitems | 删除 | 三角色 | read+write |
| POST | /createnew | 新建文件/目录 | 三角色 | read+write |
| GET | /upload | 分块预检(chunkCheck) | 三角色 | upload |
| POST | /upload | 分块上传 | 三角色 | upload |
| GET | /download | 单文件下载 | 三角色 | download |
| POST/GET | /batchdownload | 批量打包下载 | 三角色 | read+download+batchdownload |
| GET | /listusers | 用户列表 | 仅 admin | - |
| POST | /storeuser | 建用户 | 仅 admin | - |
| POST | /updateuser/{username} | 改用户 | 仅 admin | - |
| POST | /deleteuser/{username} | 删用户 | 仅 admin | - |
| POST | /savecontent | 保存文件内容 | 三角色 | read+write |
说明:表内「三角色」含 guest——guest 是否真能操作取决于其 permissions(默认 guest permissions 为空,实测不可读写)。
五、核心域逐条实测
5.1 认证域
登出(POST /logout):
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/logout" -H "X-CSRF-Token: $TOKEN"
实测回显 {"data":"Logged out"};随后 getuser 返回 guest。
改密(POST /changepassword,oldpassword+newpassword 必填):
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/changepassword" \
-H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
-d '{"oldpassword":"admin123","newpassword":"q1w2e3r4"}'
实测回显:{"data":{"role":"admin","permissions":[...7 项...],"homedir":"\/","username":"admin","name":"Admin"}},同时 private/users.json 的 bcrypt hash 更新(实测 $2y$10$Nu35... → $2y$10$CLGlz4...)。
登录失败与锁定:错误密码返回 {"data":"Login failed, please try again"};默认连续 5 次失败锁定该 IP 15 秒(配置 lockout_attempts/lockout_timeout,可收紧)。
5.2 文件域
列目录(POST /getdir):
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/getdir" \
-H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" -d '{"directory":"/"}'
实测回显:
{"data":{"location":"\/","files":[{"type":"dir","path":"\/docs","name":"docs","size":0,"time":1793341916,"permissions":755},{"type":"file","path":"\/hello.md","name":"hello.md","size":66,"time":1793341898,"permissions":644}]}}
新建(POST /createnew,type 取 file/dir):
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/createnew" \
-H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
-d '{"type":"dir","name":"docs","directory":"/"}'
实测:dir 返回 {"data":"Done"};file 类型返回 {"data":"Failed"} 但文件实际已创建(v7.16.8 已知缺陷,见第七章)。
写文件内容(POST /savecontent,自动创建目标文件):
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/savecontent" \
-H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
-d '{"directory":"/","name":"hello.md","content":"# FileGator 实测文件\n这是 B2 部署验证写入的内容。\n"}'
实测回显 {"data":"Done"}。
重命名 / 删除(renameitem 用 from/to;deleteitems 的 items 同样要对象数组):
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/renameitem" \
-H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
-d '{"from":"/empty.txt","to":"/empty-renamed.txt"}'
# {"data":"Done"}
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/deleteitems" \
-H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
-d '{"items":[{"type":"file","path":"/empty-renamed.txt"}]}'
# {"data":"Done"}
5.3 上传下载域
上传(POST /upload,multipart,resumable.js 协议参数必带):
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/upload" \
-H "X-CSRF-Token: $TOKEN" \
-F 'file=@upload-test.txt' \
-F 'resumableFilename=upload-test.txt' \
-F 'resumableRelativePath=/' \
-F 'resumableChunkNumber=1' \
-F 'resumableTotalChunks=1' \
-F 'resumableTotalSize=52' \
-F 'resumableIdentifier=uploadtesttxt52jpeg'
实测回显 {"data":"Stored"}。分块大于 1 时按 resumableChunkNumber 逐块 POST,最后一块由服务端合并落盘;漏带 resumable* 参数返回 {"data":"Error storing file"}(实测)。GET /upload 为分块预检(chunkCheck),返回已收块信息。
下载(GET /download,path 为 base64 编码的文件绝对路径):
B64=$(printf '/upload-test.txt' | base64 -w0)
curl -s -b cookies.txt -o dl-out.txt -w "HTTP:%{http_code} bytes:%{size_download} type:%{content_type}\n" \
"http://127.0.0.1:8149/?r=/download&path=$B64"
实测回显:
HTTP:200 bytes:66 type:text/plain;charset=UTF-8
路径未 base64 编码(误用 ?file=)返回 302 重定向回首页(实测)。
5.4 打包与批量下载域
打包(POST /zipitems,items 为对象数组):
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/zipitems" \
-H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
-d '{"items":[{"type":"file","path":"/hello.md"},{"type":"file","path":"/upload-test.txt"}],"destination":"/","name":"archive.zip"}'
实测返回 {"data":"Failed"} 但 repository/archive.zip(351 字节,PK 文件头合法)实际已生成——以 getdir 复核为准。
批量下载(POST 建 archive → GET 取件,这是 FileGator 的「分享」形态:打包件与会话绑定,仅创建者可下载,源码 rememberBatchArchive 逻辑):
# POST:拿 uniqid
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/batchdownload" \
-H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
-d '{"items":[{"type":"file","path":"/hello.md"},{"type":"file","path":"/upload-test.txt"}]}'
# {"data":{"uniqid":"8ec8dc043ce18598179884728d72fa942237dfcdefdfa72918bbe5ce68d6d7be"}}
# GET:拉取 zip
curl -s -b cookies.txt -o batch-out.zip -w "HTTP:%{http_code} bytes:%{size_download}\n" \
"http://127.0.0.1:8149/?r=/batchdownload&uniqid=8ec8dc043ce18598179884728d72fa942237dfcdefdfa72918bbe5ce68d6d7be"
# HTTP:200 bytes:351
解压(POST /unzipitem):{"item":"/archive.zip","destination":"/docs"} → 实测返回 {"data":"Failed"} 但两个文件已实际解压到 /docs(同款缺陷)。
5.5 用户管理域(仅 admin)
建用户(POST /storeuser):
curl -s -b cookies.txt -X POST "http://127.0.0.1:8149/?r=/storeuser" \
-H 'Content-Type: application/json' -H "X-CSRF-Token: $TOKEN" \
-d '{"username":"dev1","name":"Dev One","role":"user","homedir":"/docs","permissions":["read","write","upload","download"],"password":"q1w2e3r4"}'
实测回显:
{"data":{"role":"user","permissions":["read","write","upload","download"],"homedir":"\/docs","username":"dev1","name":"Dev One"}}
用户列表(GET /listusers)返回全部用户对象(含 homedir/permissions,不含明文密码);改用户(POST /updateuser/{username})与删用户(POST /deleteuser/{username})同构。实测 dev1(user 角色)访问 listusers 无权限(角色门槛生效);dev1 登录后 getdir 只见 homedir /docs 内文件(目录隔离生效)。
六、限流与其他约定
- 登录限流:按 IP 计失败次数,默认 5 次失败锁 15 秒(lockout_attempts/lockout_timeout 可在 configuration.php 调整);自动化脚本应处理
Login failed后的退避。 - 无全局请求限流:路由表与源码未见令牌桶等限流层,批量脚本自控节奏。
- 上传体积链:前端
upload_max_size(默认 100MB)→ 分块大小(默认 1MB)→ PHP 运行时限制,调参联动见 《FileGator v7.16.8 配置参数详解》 第五章。 - 会话有效期:PHP 默认会话生命周期,脚本长跑任务建议定期重登或处理 302/guest 响应后自动重连。
七、排障实录(实测沉淀)
- POST 全部返回 HTTP 200 + 空响应体
CSRF token 缺失/过期。判定方法:查
private/logs/app.log是否出现Csrf token not valid(实测记录)。修复:重新 GET 取响应头X-CSRF-Token并回带;登录后必须重取(会话迁移使旧 token 失效,实测踩坑两次)。 /login、/getconfig直接访问 404 官方镜像无 URL 重写,必须用/?r=/端点形态(实测 404 vs 200 对照)。- createnew(file)/zipitems/unzipitem 返回 Failed 但操作成功 v7.16.8 源码缺陷:控制器对无返回值的适配器方法取反判断(Filesystem::createFile 与 ZipArchiver::storeArchive 均无 return 语句,源码实查)。脚本化处理:忽略该返回值,用 getdir/宿主目录复核实际结果。
- items 传字符串数组报 PHP Warning/Fatal
zipitems/batchdownload/deleteitems 的 items 必须是
[{"type":"file","path":"..."}]对象数组;传["/hello.md"]触发Attempt to read property "type" on string(实测日志),zipitems 场景还会连锁 Fatal。 - 上传 Error storing file 缺 resumable* 参数组(前端协议必带),按 5.3 参数清单补全。
- 下载 302 回首页 path 参数未做 base64 编码,或文件路径在当前账号 homedir 之外(权限边界,实测行为一致)。
八、参考链接
- 路由表全集(roles/permissions 门槈权威来源):https://github.com/filegator/filegator/blob/master/backend/Controllers/routes.php (查询日期 2026-10-30)
- 认证适配器(会话与用户库实现):https://github.com/filegator/filegator/blob/master/backend/Services/Auth/Adapters/JsonFile.php (查询日期 2026-10-30)
- 本专栏姊妹篇:《FileGator 介绍与选型指南》、《FileGator v7.16.8 Docker Compose 部署指南》、《FileGator v7.16.8 配置参数详解》