基于 Go 的轻量随机图服务,支持:
- PC / 手机随机图接口
- 302 跳转静态资源(CDN 友好)
- JSON 返回静态图片 URL
- Token 登录后上传(会话鉴权)
- 图片标签(tag)索引与按标签随机
- 后台标签管理页面(查看图片、覆盖/追加标签、删除图片、查看磁盘占用)
- 上传页拖拽选择 + 点击上传 + 可附加标签
- 接口调用统计与定时落盘
- 公网部署基础加固(限速、来源校验、安全响应头、CORS、访问日志)
/api/web:随机 PC 图(302 到/images/...)/api/m:随机手机图(302 到/images/...)/api/web?tag=anime:按标签随机 PC 图/api/m?tag=anime:按标签随机手机图
/api/web/json:返回 PC 图静态 URL/api/m/json:返回手机图静态 URL/api/web/json?tag=anime:按标签返回 PC 图 URL/api/m/json?tag=anime:按标签返回手机图 URL- JSON 与统计接口默认支持公开 CORS,便于第三方前端以
fetch()调用。
POST /api/login:提交 token 登录,写入 HttpOnly 会话 CookiePOST /api/logout:登出并清理会话GET /api/auth/status:查看当前是否登录
POST /api/upload- 表单字段:
file:图片文件category:web或mtags:可选,逗号分隔(如anime,girl,night)
- 说明:
- 不再通过表单 token 上传
- 必须先登录再上传
GET /api/admin/tags:返回标签列表与图片数量GET /api/admin/images:分页查询图片+标签- 参数:
category、tag、page、pageSize
- 参数:
POST /api/admin/image/tags:设置图片标签- JSON:
{"path":"web/xxx.webp","tags":["anime"],"mode":"replace|append"}
- JSON:
POST /api/admin/image/delete:删除图片并清理标签- JSON:
{"path":"web/xxx.webp"}
- JSON:
GET /api/admin/system:查看图片数量、磁盘占用和可选空间上限
GET /api/stats- 统计驻留内存,定时写入
stats.json
GET /healthz- 返回服务状态、基础检查项和服务器 UTC 时间,适合反向代理或监控探活。
- 页面:
/public/* - 图片:
/images/* - 图片响应包含缓存头:
Cache-Control: public, max-age=31536000, immutable
这意味着随机接口可通过 302 指向静态图片,由 CDN 长缓存图片资源。
/public/index.html:首页(接口入口 + 统计 + 背景刷新)/public/login.html:Token 登录页/public/upload.html:上传页(拖拽/点选文件,点击上传按钮提交,可附加标签)/public/admin.html:后台标签管理页
One-picture-API/
├─ config.go
├─ main.go
├─ security.go
├─ tagging.go
├─ Dockerfile
├─ docker-compose.yml
├─ .env.example
├─ tokens.example.json
├─ tags_index.example.json
├─ tokens.json
├─ stats.json
├─ tags_index.json
├─ images/
│ ├─ web/
│ └─ m/
└─ public/
├─ index.html
├─ login.html
├─ upload.html
├─ common.css
└─ common.js
说明:tokens.json、stats.json、tags_index.json 和真实图片文件属于本地运行数据,默认不进入 Git;仓库只保留 images/**/.gitkeep 作为目录占位。
不要把真实登录 Token 提交到仓库。首次运行前二选一:
cp tokens.example.json tokens.json然后编辑 tokens.json,把示例值替换为长度 >= 32 的随机字符串;或者直接通过环境变量提供:
OPAPI_TOKENS="your-random-token" go run .在项目目录执行:
go run .启动后访问:
http://localhost:8080
复制示例环境变量:
cp .env.example .env编辑 .env,至少替换 OPAPI_TOKENS,然后启动:
docker compose up -d --buildCompose 默认把运行数据放到本地 data/:
data/
├─ images/
├─ stats.json
└─ tags_index.json
默认监听地址为 127.0.0.1:8080,推荐放在 Nginx / Caddy / Cloudflare Tunnel 等反向代理后面,再由反代负责 HTTPS、访问日志、压缩与证书续期。
如果确实需要程序直接监听所有网卡,请显式设置:
OPAPI_ADDR=":8080" go run .HTTPS 部署时建议同时设置:
OPAPI_COOKIE_SECURE=true如果后台页面和 API 不在同一个域名,需要配置允许的来源:
OPAPI_TRUSTED_ORIGINS="https://example.com"如果服务运行在可信反向代理后,并希望登录限速使用 X-Forwarded-For / X-Real-IP 中的真实客户端 IP,可设置:
OPAPI_TRUST_PROXY=true不要在未配置可信反代时开启该选项。
推荐架构:
Client
↓ HTTPS
Caddy / Nginx / Cloudflare
↓ localhost
One-picture-API 127.0.0.1:8080
docs/Caddyfile.example 提供了一个最小 Caddy 反向代理示例。
{
"tokens": [
"请替换为你的高强度token"
]
}建议使用长度 >= 32 的随机字符串,并定期轮换。
| 变量 | 默认值 | 说明 |
|---|---|---|
OPAPI_ADDR |
127.0.0.1:8080 |
监听地址;如需直接公网监听可设为 :8080 |
OPAPI_IMAGES_DIR |
images |
图片根目录,下面需要有 web/ 和 m/ |
OPAPI_PUBLIC_DIR |
public |
前端静态页面目录 |
OPAPI_TOKENS_FILE |
tokens.json |
登录 Token 文件路径 |
OPAPI_TOKENS |
空 | 额外登录 Token,支持逗号、分号、空白分隔 |
OPAPI_STATS_FILE |
stats.json |
统计文件路径,启动时会读取,运行中会定时落盘 |
OPAPI_TAGS_FILE |
tags_index.json |
标签索引文件路径 |
OPAPI_COOKIE_SECURE |
false |
HTTPS 部署时建议设为 true |
OPAPI_TRUSTED_ORIGINS |
空 | 允许跨域发起后台写请求的来源,支持逗号/分号/空白分隔 |
OPAPI_PUBLIC_CORS_ORIGINS |
* |
公开只读接口的 CORS 允许来源 |
OPAPI_TRUST_PROXY |
false |
是否信任反向代理传入的真实客户端 IP 头 |
OPAPI_ACCESS_LOG |
true |
是否输出访问日志 |
OPAPI_DEBUG_ERRORS |
false |
是否向客户端返回详细错误;公网建议保持 false |
OPAPI_LOGIN_MAX_FAILS |
8 |
登录限速窗口内最大失败次数,设为 0 可关闭 |
OPAPI_LOGIN_WINDOW |
10m |
登录失败计数窗口 |
OPAPI_LOGIN_BLOCK |
15m |
触发登录限速后的封禁时间 |
OPAPI_MAX_STORAGE_BYTES |
0 |
图片总存储上限,单位字节;0 表示不限制 |