S3 对象存储
Cloudflare R2/S3 的 CORS、密钥变量、签名上传 URL 与头像代理访问配置指南。
MuseMVP 封装了通用 S3 协议的文件上传接口,无缝兼容 AWS S3、Cloudflare R2 或自建 MinIO。用于用户头像上传,并为每个用户提供账户内的 Storage 资产管理页,可按需扩展至其他文件类型。
配置步骤
配置跨域

[
{
"AllowedOrigins": [
"*"
],
"AllowedMethods": [
"GET",
"POST",
"PUT",
"DELETE",
"HEAD"
],
"AllowedHeaders": [
"*"
],
"ExposeHeaders": [
"ETag"
],
"MaxAgeSeconds": 3600
}
]提示
配置跨域是为了让前端可以访问 Cloudflare R2 存储桶,请根据实际需求修改,尤其是 AllowedOrigins 需要根据实际需求修改。
创建 S3_ACCESS_KEY_ID、S3_SECRET_ACCESS_KEY 和 S3_ENDPOINT

S3_ACCESS_KEY_ID="55xxxc34b0"
S3_SECRET_ACCESS_KEY="08xxx625b1cc0cbe"
S3_ENDPOINT="https://xxx.r2.cloudflarestorage.com"图片代理前缀
- 创建一个 Worker,并根据你的部署环境配置代理路由
export const config = {
storage: {
proxyUrls: {
avatarsFile: resolveUrlValue(
process.env.NEXT_PUBLIC_AVATARS_PROXY_URL,
"",
),
},
},
};上传对象路径规则
头像上传采用两层路径结构:
- 前端传入相对路径(
path),例如:2026_02_18_avatar_xxx.png - 后端统一加用户目录前缀(
userId)作为最终对象 key
最终 key 格式:${userId}/${path}
示例:
userId = user_abc123path = 2026_02_18_avatar_3f2c...png- 对象存储 key =
user_abc123/2026_02_18_avatar_3f2c...png
每位用户的静态资源落在自己的 userId 目录下,便于按用户维度检索、迁移与清理。
代理前缀与访问 URL
UserAvatar 组件有两种头像地址处理方式:
avatarUrl以http开头:直接使用(完整外链)- 其他情况:按
${config.storage.proxyUrls.avatarsFile}/${avatarUrl}拼接
推荐配置
将 config.storage.proxyUrls.avatarsFile(或 NEXT_PUBLIC_AVATARS_PROXY_URL)指向 CDN 或对象存储的公开读域名,例如 https://static.example.com。
资产管理页
每位登录用户都拥有一个内置页面,可浏览、预览、下载与删除自己的存储文件。
页面路由
/app/settings/storage,需登录访问。入口位于账户侧边栏与头像下拉菜单。
API 端点
页面由 4 个端点支撑,均挂载 authMiddleware,basePath 为 /assets(实现见 src/backend/api/routes/assets/):
| 端点 | 说明 |
|---|---|
GET /api/assets | 分页列出当前用户文件(默认每页 50,最大 100) |
GET /api/assets/usage | 返回对象数与总字节(聚合上限 10,000 对象) |
POST /api/assets/download-url | 生成 presigned 下载链接(有效期 900 秒) |
POST /api/assets/delete | 批量删除(单次最多 200 个 key,按 key 返回成功/失败) |
安全模型
- 所有操作严格限定在调用者自己的
${userId}/前缀内 - key 做防目录穿越校验,相对 key 最长 512 字符
- 预览 URL 拼接自
config.storage.proxyUrls.avatarsFile,需配置NEXT_PUBLIC_AVATARS_PROXY_URL预览才可用 - S3 环境变量缺失时页面显示「存储未配置」状态(错误码
STORAGE_ENV_MISSING)
UI 组件
UI 位于 src/modules/settings/components/assets/:AssetManager、AssetTable 与 AssetActionsMenu。
必填存储环境变量
以下 3 个变量必须同时存在,否则后端不会签发上传 URL:
| 变量名 | 说明 |
|---|---|
S3_ACCESS_KEY_ID | S3 兼容服务的 Access Key |
S3_SECRET_ACCESS_KEY | S3 兼容服务的 Secret Key |
S3_ENDPOINT | 服务端点(如 https://xxx.r2.cloudflarestorage.com) |
当缺失时:
- 后端返回
503,错误码STORAGE_ENV_MISSING - 前端头像上传会触发 warning toast,并提示缺失变量名
相关配置项
src/config/index.ts 的 storage 分区:
| 配置项 | 说明 |
|---|---|
storage.meta | S3 服务端连接参数 |
storage.bucketNames.avatars | 头像 bucket(支持 NEXT_PUBLIC_AVATARS_BUCKET_NAME 覆盖) |
storage.proxyUrls.avatarsFile | 头像访问前缀域名(支持 NEXT_PUBLIC_AVATARS_PROXY_URL 覆盖) |


