溯仑智算
溯仑智算 SU.RUN开发者文档
获取接入支持
溯仑智算
溯仑智算 SU.RUN
开发者文档
开始使用
文档中心
阅读路径、接入顺序与专题总览
存储接入快速开始
第一次接入时优先阅读
存储接入总览
能力边界、使用路径与整体说明
本地配置与验证指南
在本地完成示例接口与最小验证
上传与下载
授权上传指南
浏览器、App 与客户端上传方式
授权下载指南
受控下载、权限判断与短时授权
前端直传安全规范
长期密钥保护与权限边界
大文件上传实战
大文件上传、重试与断点续传
规划与治理
文件路径命名规范
存储桶、路径、目录与归档规则
自定义域名接入
品牌化访问、证书与上线准备
接口说明
服务端接入方式、鉴权边界与返回结构
最小后端接入示例
上传下载授权与确认入库的完整串联
代码示例
JavaScript、Python 与 Go 接入示例
AI 与工作流
AI 环境接入说明
常见 AI 环境的接入说明
AI 训练数据与结果回写规范
模型、数据集、日志与输出治理
排障与帮助
错误码与问题排查
常见异常定位与恢复建议
接入常见问题总览
按角色整理的常见问题说明
支持中心
获取接入支持
获取接入支持
开始使用
文档中心存储接入快速开始存储接入总览本地配置与验证指南
上传与下载
授权上传指南授权下载指南前端直传安全规范大文件上传实战
规划与治理
文件路径命名规范自定义域名接入接口说明最小后端接入示例代码示例
AI 与工作流
AI 环境接入说明AI 训练数据与结果回写规范
排障与帮助
错误码与问题排查接入常见问题总览
当前文档
在本地完成示例接口与最小验证
文档中心

本地配置与验证指南

这篇文档主要帮助团队把仓库里已有的 `/api/storage/presign-upload` 和 `/api/storage/presign-download` 跑起来,在本地完成一轮最小上传下载验证。

接入支持
support@su.run

本地启动 / 登录态获取 / 上传下载验证 / requestId 核对

开始前准备

建议先确认这四项内容

  • 本地已经配置好存储接入参数,并可连通目标桶。
  • 当前登录用户可获取 Bearer Token,用于请求示例 route。
  • 本地开发环境可正常启动 Next.js 项目,并访问 docs 与 API 路由。
  • 测试文件建议先从小文件开始,例如 png、txt 或 json,方便快速回看返回值。

当前可用的示例接口

这几条 route 可以直接用于验证

上传授权 Route
/api/storage/presign-upload

接收 fileName、contentType、resourceType,返回 uploadUrl、objectKey、bucket、expiresIn 和 requestId。

确认入库 Route
/api/storage/confirm-upload

接收 objectKey、fileName、contentType、size 等字段,确认对象已存在并返回统一 asset 结构。

下载授权 Route
/api/storage/presign-download

接收 objectKey,校验当前用户只能访问自己的示例目录,再返回 downloadUrl、bucket、expiresIn 和 requestId。

配置服务端环境变量

示例 route 读取的是 SURUN 开头的变量

这一步只影响本地示例 route 的可用性,不会改动现有业务逻辑。补充存储连接信息后,重启开发服务器即可。

SURUN_S3_ENDPOINT=https://your-s3-endpoint
SURUN_S3_REGION=auto
SURUN_ACCESS_KEY_ID=your-access-key
SURUN_SECRET_ACCESS_KEY=your-secret-key
SURUN_DEFAULT_BUCKET=media-assets

获取登录态令牌

示例 route 通过 Bearer Token 识别当前用户

已接入前端登录时,可直接从当前 session 里读取 access_token;如在 Postman 或 curl 里验证,也需要把同一令牌放进 Authorization 头。

const {
  data: { session },
} = await supabase.auth.getSession();

const accessToken = session?.access_token;

if (!accessToken) {
  throw new Error('当前没有可用登录态');
}

建议验证顺序

建议按固定顺序逐步完成验证

STEP 1
第一步:补全本地环境变量

这组示例 route 不会读取浏览器里的配置,而是直接在服务端读取 SURUN_* 变量。只要缺少必要项,接口就会返回 demo_storage_unavailable。

STEP 2
第二步:准备登录态 Bearer Token

示例 route 会从 Authorization 头里取 Bearer Token,再解析当前用户。没有登录态时,请先确认本地登录流程和 access_token 获取方式。

STEP 3
第三步:先拿上传授权,再真正上传文件

正确顺序是先 POST `/api/storage/presign-upload`,拿到 uploadUrl 与 objectKey,再对 uploadUrl 发 PUT。不要跳过签名阶段直接拼 URL。

STEP 4
第四步:上传完成后立刻确认入库

现在仓库里已经有 `/api/storage/confirm-upload`。建议上传成功后立刻调用它,确认对象存在、记录 requestId,并把统一的 asset 结构返回给前端或业务层。

STEP 5
第五步:拿 objectKey 再申请下载授权

确认入库通过后,再用同一个 objectKey 去调用 `/api/storage/presign-download`。下载接口不会帮你猜路径,路径必须与上传返回值一致。

先调用上传授权接口

先拿 uploadUrl 和 objectKey,再传文件本体

curl 示例
curl -X POST http://localhost:3000/api/storage/presign-upload \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
  -d '{
    "fileName": "demo-cover.png",
    "contentType": "image/png",
    "resourceType": "project-cover"
  }'
预期返回
{
  "success": true,
  "bucket": "media-assets",
  "objectKey": "docs-demo/<user-id>/project-cover/2026/06/abc123-demo-cover.png",
  "uploadUrl": "https://your-upload-url",
  "expiresIn": 600,
  "requestId": "req_xxx"
}

真正上传文件

PUT 目标一定是 uploadUrl,不是业务 route

curl -X PUT "<UPLOAD_URL>" \
  -H "Content-Type: image/png" \
  --data-binary "@./demo-cover.png"

前端 fetch 版本

浏览器验证时最小只需要这一段

const response = await fetch('/api/storage/presign-upload', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${accessToken}`,
  },
  body: JSON.stringify({
    fileName: file.name,
    contentType: file.type,
    resourceType: 'project-cover',
  }),
});

const result = await response.json();

再调用下载授权接口

下载验证时直接复用上传返回的 objectKey

当前示例下载接口不会替你查业务主表,它只认 `objectKey` 和当前登录用户。因此最稳的做法是直接使用上传接口返回的原始对象路径。

curl -X POST http://localhost:3000/api/storage/presign-download \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
  -d '{
    "objectKey": "docs-demo/<user-id>/project-cover/2026/06/abc123-demo-cover.png"
  }'

补上确认入库调用

如果要更完整验证,建议把这一步也走通

这一步会让服务端重新确认对象确实已经存在于当前示例目录下,并返回统一的 `asset` 结构。后续如需接数据库、项目素材表或任务记录,可以直接以这一步为基础继续扩展。

curl -X POST http://localhost:3000/api/storage/confirm-upload \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
  -d '{
    "objectKey": "docs-demo/<user-id>/project-cover/2026/06/abc123-demo-cover.png",
    "fileName": "demo-cover.png",
    "contentType": "image/png",
    "size": 248731,
    "resourceType": "project-cover",
    "projectId": "proj_xxx"
  }'

验证完成的判断标准

满足这些条件,就说明最小链路已经跑通

  • 上传授权响应里有 success、objectKey、uploadUrl、expiresIn、requestId。
  • 对 uploadUrl 发 PUT 后返回 200 或 204,而不是浏览器被 CORS 或 Content-Type 拦下。
  • 确认入库接口返回 asset.id、asset.status、confirmedAt,说明对象已被服务端回查确认。
  • 下载授权返回的 objectKey 与上传返回的一致,没有手写错前缀。
  • requestId 已进入日志或控制台输出,后续核对时可以继续关联。
  • 示例对象都落在 docs-demo/{userId}/... 目录下,没有越权访问其他目录。

接入常见问题

为什么上传授权接口直接返回 demo_storage_unavailable?

说明服务端缺少必须的 SURUN_* 环境变量,或者变量值为空。先检查本地 `.env.local` 是否真正被开发服务器读取。

为什么下载授权返回 object_access_denied?

因为当前 objectKey 不在 `docs-demo/{userId}/` 目录下。这个限制是故意做的,用来确保示例接口不会跨用户目录签发下载。

为什么 PUT 上传成功了,但业务系统里看不到文件?

如果尚未调用 `/api/storage/confirm-upload`,它仍然只是一条已上传对象;真正业务里通常要等确认入库成功后,页面才把它当成正式资源展示。

上一篇
存储接入总览
能力边界、使用路径与整体说明
下一篇
授权上传指南
浏览器、App 与客户端上传方式
更多帮助

你可能还需要这些帮助入口

文档中心帮助你完成接入,客户服务页帮助你了解采购、支持与服务信息。

邮件支持

需要迁移协助或接入支持时,可以直接进入邮件支持入口。

进入支持中心

客户常见问题

采购、测试申请、迁移安排与售后问题,可先查看这份常见问题说明。

查看常见问题

价格与采购说明

需要确认容量区间、采购方式、续费与对账说明时,可从这里继续查看。

查看价格说明