188 lines
5.9 KiB
Markdown
188 lines
5.9 KiB
Markdown
# 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 邮箱确认与密码重置
|
||
|
||
## 本地启动
|
||
|
||
复制配置并生成开发密钥:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
openssl rand -hex 32
|
||
```
|
||
|
||
把生成值写入 `.env` 的 `SECRET_KEY`,然后安装依赖:
|
||
|
||
```bash
|
||
uv sync
|
||
```
|
||
|
||
准备一个可访问的 PostgreSQL 数据库,并在 `.env` 中填写实际连接信息:
|
||
|
||
```dotenv
|
||
DATABASE_URL=postgresql+asyncpg://用户名:密码@主机:5432/数据库名
|
||
```
|
||
|
||
应用和 Alembic 都只从 `.env` 读取数据库连接,不需要在其他配置文件中重复填写。
|
||
|
||
创建表并写入十种云类型、可选初始管理员:
|
||
|
||
```bash
|
||
uv run alembic upgrade head
|
||
uv run python -m app.seed
|
||
```
|
||
|
||
启动开发服务器:
|
||
|
||
```bash
|
||
uv run uvicorn app.main:app --reload
|
||
```
|
||
|
||
- API:`http://localhost:8000/api/v1`
|
||
- Swagger:`http://localhost:8000/docs`
|
||
- 健康检查:`http://localhost:8000/api/v1/health`
|
||
|
||
## 认证约定
|
||
|
||
登录成功后响应包含有效期较短的 `access_token`。前端在请求头中发送:
|
||
|
||
```text
|
||
Authorization: Bearer <access_token>
|
||
```
|
||
|
||
Refresh Token 只保存在 HttpOnly Cookie 中。前端调用 `/api/v1/auth/refresh` 和 `/api/v1/auth/logout` 时必须允许 Cookie:
|
||
|
||
```ts
|
||
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 缩略图。新图片状态始终为 `pending`,`user_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` 中找到。首次运行先复制该文件:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
其中关键配置包括:
|
||
|
||
- `DATABASE_URL`:异步 SQLAlchemy 连接串,PostgreSQL 使用 `postgresql+asyncpg://`
|
||
- `SECRET_KEY`:JWT 签名密钥,生产环境至少 32 个字符
|
||
- `FRONTEND_URL`:认证邮件中的前端地址
|
||
- `PUBLIC_BASE_URL`:API 和图片公开地址
|
||
- `CORS_ORIGINS`:逗号分隔的前端来源
|
||
- `UPLOAD_DIR`:持久化图片目录
|
||
- `EMAIL_DELIVERY_MODE`:`console` 或 `smtp`
|
||
- `ADMIN_EMAIL`、`ADMIN_PASSWORD`:执行 seed 时可选创建管理员
|
||
|
||
生产环境还必须设置 `ENVIRONMENT=production`、`COOKIE_SECURE=true`,并通过 HTTPS 访问。
|
||
|
||
## 数据库迁移(Alembic)
|
||
|
||
Alembic 用于管理数据库结构版本,作用类似于数据库结构的 Git。它会记录建表、增加字段、创建索引等变更,使不同环境中的数据库结构与代码保持一致,但不会负责启动 PostgreSQL 服务。
|
||
|
||
项目中的相关文件:
|
||
|
||
- `app/models.py`:SQLAlchemy 数据模型,也是当前期望的数据库结构
|
||
- `alembic/versions/`:按版本保存数据库迁移脚本
|
||
- `alembic/env.py`:加载模型,并通过 `.env` 获取 `DATABASE_URL`
|
||
- `alembic.ini`:Alembic 的基础配置,不保存数据库账号或密码
|
||
|
||
首次初始化数据库或拉取到新的迁移后,升级到最新版本:
|
||
|
||
```bash
|
||
uv run alembic upgrade head
|
||
```
|
||
|
||
修改 SQLAlchemy 模型后,先生成迁移脚本并检查生成内容,再执行升级:
|
||
|
||
```bash
|
||
uv run alembic revision --autogenerate -m "describe change"
|
||
uv run alembic upgrade head
|
||
```
|
||
|
||
查看当前数据库版本和迁移历史:
|
||
|
||
```bash
|
||
uv run alembic current
|
||
uv run alembic history
|
||
```
|
||
|
||
回退最近一次迁移:
|
||
|
||
```bash
|
||
uv run alembic downgrade -1
|
||
```
|
||
|
||
回退操作可能导致字段或数据被删除,执行前应先检查迁移脚本并备份数据库。
|
||
|
||
应用使用 SQLAlchemy 连接池,所有外键和主要画廊、地图、个人主页、审核查询均有对应索引。应用数据库账号不应使用 PostgreSQL 超级用户。
|
||
|
||
## 验证
|
||
|
||
```bash
|
||
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。
|