Files
opencloud-backend/README.md
T
2026-07-18 20:32:51 +08:00

5.9 KiB
Raw Blame History

OpenCloud Backend

OpenCloud 的 FastAPI 后端,替代原项目中的 Supabase Database、Auth 和 Storage。后端提供邮箱密码认证、可撤销刷新会话、云图上传与缩略图、地图/画廊查询、图鉴解锁、个人主页和管理员审核。

技术栈

  • Python 3.13、FastAPI、Pydantic
  • PostgreSQL 17、SQLAlchemy 2(异步)、Alembic
  • Argon2 密码哈希、JWT Access Token、数据库 Refresh Session
  • 本地持久化图片目录、Pillow 图片验证和缩略图生成
  • SMTP 邮箱确认与密码重置

本地启动

复制配置并生成开发密钥:

cp .env.example .env
openssl rand -hex 32

把生成值写入 .envSECRET_KEY,然后安装依赖:

uv sync

准备一个可访问的 PostgreSQL 数据库,并在 .env 中填写实际连接信息:

DATABASE_URL=postgresql+asyncpg://用户名:密码@主机:5432/数据库名

应用和 Alembic 都只从 .env 读取数据库连接,不需要在其他配置文件中重复填写。

创建表并写入十种云类型、可选初始管理员:

uv run alembic upgrade head
uv run python -m app.seed

启动开发服务器:

uv run uvicorn app.main:app --reload
  • APIhttp://localhost:8000/api/v1
  • Swaggerhttp://localhost:8000/docs
  • 健康检查:http://localhost:8000/api/v1/health

认证约定

登录成功后响应包含有效期较短的 access_token。前端在请求头中发送:

Authorization: Bearer <access_token>

Refresh Token 只保存在 HttpOnly Cookie 中。前端调用 /api/v1/auth/refresh/api/v1/auth/logout 时必须允许 Cookie

fetch(url, { credentials: 'include' })

开发环境默认 EMAIL_DELIVERY_MODE=console,邮箱确认和密码重置链接会输出到后端日志。如需真实发信,请在 .env 中配置 SMTP 参数并将 EMAIL_DELIVERY_MODE 改为 smtp

主要接口

认证

  • POST /api/v1/auth/register
  • POST /api/v1/auth/resend-confirmation
  • POST /api/v1/auth/confirm-email
  • POST /api/v1/auth/login
  • POST /api/v1/auth/refresh
  • POST /api/v1/auth/logout
  • GET /api/v1/auth/me
  • POST /api/v1/auth/forgot-password
  • POST /api/v1/auth/reset-password
  • PATCH /api/v1/auth/password

云图和图鉴

  • GET/POST /api/v1/clouds
  • GET /api/v1/clouds/map
  • GET/PATCH/DELETE /api/v1/clouds/{id}
  • POST /api/v1/clouds/batch-delete
  • GET /api/v1/cloud-types
  • GET /api/v1/cloud-types/{id}/clouds
  • GET /api/v1/collections/me

上传使用 multipart/form-data,文件字段为 image;服务端自行验证、重编码原图并生成 JPEG 缩略图。新图片状态始终为 pendinguser_id 从 Access Token 获取,经纬度在服务端保留两位小数。

用户和管理后台

  • GET /api/v1/profiles/{user_id}
  • PATCH /api/v1/profiles/me
  • GET /api/v1/profiles/{user_id}/clouds
  • GET /api/v1/admin/stats
  • GET/PATCH /api/v1/admin/users
  • GET /api/v1/admin/clouds
  • PATCH /api/v1/admin/clouds/status
  • PATCH /api/v1/admin/clouds/visibility
  • POST /api/v1/admin/clouds/batch-delete

精确的请求和响应模型以 Swagger/OpenAPI 为准。

环境变量

所有可调配置均可在 .env.example 中找到。首次运行先复制该文件:

cp .env.example .env

其中关键配置包括:

  • DATABASE_URL:异步 SQLAlchemy 连接串,PostgreSQL 使用 postgresql+asyncpg://
  • SECRET_KEY:JWT 签名密钥,生产环境至少 32 个字符
  • FRONTEND_URL:认证邮件中的前端地址
  • PUBLIC_BASE_URLAPI 和图片公开地址
  • CORS_ORIGINS:逗号分隔的前端来源
  • UPLOAD_DIR:持久化图片目录
  • EMAIL_DELIVERY_MODEconsolesmtp
  • ADMIN_EMAILADMIN_PASSWORD:执行 seed 时可选创建管理员

生产环境还必须设置 ENVIRONMENT=productionCOOKIE_SECURE=true,并通过 HTTPS 访问。

数据库迁移(Alembic

Alembic 用于管理数据库结构版本,作用类似于数据库结构的 Git。它会记录建表、增加字段、创建索引等变更,使不同环境中的数据库结构与代码保持一致,但不会负责启动 PostgreSQL 服务。

项目中的相关文件:

  • app/models.pySQLAlchemy 数据模型,也是当前期望的数据库结构
  • alembic/versions/:按版本保存数据库迁移脚本
  • alembic/env.py:加载模型,并通过 .env 获取 DATABASE_URL
  • alembic.ini:Alembic 的基础配置,不保存数据库账号或密码

首次初始化数据库或拉取到新的迁移后,升级到最新版本:

uv run alembic upgrade head

修改 SQLAlchemy 模型后,先生成迁移脚本并检查生成内容,再执行升级:

uv run alembic revision --autogenerate -m "describe change"
uv run alembic upgrade head

查看当前数据库版本和迁移历史:

uv run alembic current
uv run alembic history

回退最近一次迁移:

uv run alembic downgrade -1

回退操作可能导致字段或数据被删除,执行前应先检查迁移脚本并备份数据库。

应用使用 SQLAlchemy 连接池,所有外键和主要画廊、地图、个人主页、审核查询均有对应索引。应用数据库账号不应使用 PostgreSQL 超级用户。

验证

uv run pytest -q
uv run python -m compileall -q app main.py
uv run alembic upgrade head --sql

测试覆盖注册、邮箱确认、登录、资料修改、上传、缩略图、图鉴解锁、管理员审核、画廊、地图和删除的完整流程。

部署注意事项

  • data/uploads 必须挂载到持久化磁盘并纳入备份。
  • PostgreSQL 和上传目录需要分别制定备份与恢复方案。
  • 单机部署可由 FastAPI 提供 /media;高流量部署建议由 Nginx/Caddy 直接服务该目录。
  • is_hidden 与原 Supabase 公共 bucket 行为一致,只阻止页面发现,知道图片 URL 的人仍可直接访问。若需要真正私密图片,应改为鉴权下载或短期签名 URL。