EasyStarter logoEasyStarter
存储服务

阿里云 OSS 存储(适合中国大陆业务)

将 EasyStarter 的存储 Provider 切换到阿里云对象存储 OSS,复用 RAM AccessKey

阿里云 OSS 存储

EasyStarter 内置了阿里云 对象存储 OSS 作为存储服务商,可以与默认的 Cloudflare R2 自由切换。服务端通过 OSS REST API V4 签名直接调用,不依赖任何 Node.js SDK,可以在 Cloudflare Workers Runtime 下直接运行。

如果你的服务主要面向中国大陆用户,使用阿里云 OSS 通常能获得更稳定的访问速度和更低的出口流量成本;与上一节的 阿里云手机号登录 共用同一对 RAM AccessKey,运维上也更简单。

项目当前配置
上传/下载/列举/删除OSS REST API V4 + OSS4-HMAC-SHA256 签名
服务端 Providerapps/server/src/storage/providers/aliyun-oss.ts
Provider 注册位置apps/server/src/storage/index.ts
配置开关packages/app-config/src/app-config.ts 中的 common.storage.provider
文件访问路径${SERVER_URL}/api/storage/aliyun-oss/<key>(通过服务端代理,OSS Bucket 无需公开)

EasyStarter 现有的 avatarattachment 上传类型、文件大小和 MIME 类型限制对所有 Provider 通用,切换到 OSS 后业务代码无需修改。

所需环境变量

# 与阿里云手机号登录共用同一对 RAM AccessKey
ALIBABA_CLOUD_ACCESS_KEY_ID=
ALIBABA_CLOUD_ACCESS_KEY_SECRET=

# OSS 专属
ALIYUN_OSS_BUCKET=
ALIYUN_OSS_REGION=
ALIYUN_OSS_ENDPOINT=

变量说明:

变量含义示例
ALIBABA_CLOUD_ACCESS_KEY_IDRAM 用户 AccessKey ID,服务端调用 OSS 的长期凭证LTAI5tXXXXXXXXXXXXXXXXX
ALIBABA_CLOUD_ACCESS_KEY_SECRETRAM 用户 AccessKey Secret,仅创建时显示一次XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ALIYUN_OSS_BUCKETOSS Bucket 名称,不含域名your-app-bucket
ALIYUN_OSS_REGIONBucket 所在地域 ID,签名时作为 region scopecn-hangzhou
ALIYUN_OSS_ENDPOINTOSS 访问域名,不要带 Bucket 前缀和协议头oss-cn-hangzhou.aliyuncs.com

ALIYUN_OSS_ENDPOINT 必须填外网访问域名,例如 oss-cn-hangzhou.aliyuncs.com。如果你写成 your-app-bucket.oss-cn-hangzhou.aliyuncs.com,Provider 内部会再次拼接一次 Bucket,导致请求路径错误。

如果你已经按照 阿里云手机号登录 配置过 ALIBABA_CLOUD_ACCESS_KEY_ID / ALIBABA_CLOUD_ACCESS_KEY_SECRET,可以直接复用同一对密钥,只需要为同一个 RAM 用户追加 OSS 权限。

开通对象存储 OSS 服务

先确认阿里云账号已经开通对象存储 OSS 服务,并完成实名认证。

产品页面:阿里云对象存储 OSS,在页面顶部点击 立即开通 即可。

创建 OSS Bucket

官方文档:创建存储空间

  1. 登录 OSS 控制台
  2. 点击 Bucket 列表创建 Bucket
  3. 填写 Bucket 名称,例如 your-app-bucket(全局唯一,3-63 字符,仅小写字母、数字、短横线)
  4. 选择 地域,例如 华东1(杭州),对应 region ID cn-hangzhou
  5. 读写权限保持默认的 私有(文件通过服务端代理访问,Bucket 不需要公开)
  6. 其它选项按默认即可,点击 完成创建

记录以下信息:

  • Bucket 名称 → ALIYUN_OSS_BUCKET
  • 地域 ID(控制台 Bucket 概览页的 地域 字段,例如 oss-cn-hangzhou 中的 cn-hangzhou)→ ALIYUN_OSS_REGION
  • 外网访问 Endpoint(Bucket 概览页的 Endpoint(外网访问) 字段,例如 oss-cn-hangzhou.aliyuncs.com)→ ALIYUN_OSS_ENDPOINT

为 RAM 用户授予 OSS 权限

推荐使用 RAM 用户的 AccessKey,不要直接使用阿里云主账号 AccessKey。如果你已经按照 阿里云手机号登录 创建过 RAM 用户,可以直接给同一个用户追加授权。

  1. 登录 阿里云 RAM 控制台
  2. 进入 身份管理用户,选中目标 RAM 用户
  3. 点击 权限管理新增授权
  4. 资源范围选择 账号级别,在 权限策略 中搜索并勾选系统策略 AliyunOSSFullAccess,然后点击 确认新增授权

在 RAM 新增授权弹窗中勾选 AliyunOSSFullAccess 系统策略

这是阿里云官方推荐的做法,挂载系统策略后该 RAM 用户即可读写 OSS。

获取或复用 AccessKey

官方文档:创建 AccessKey

如果还没有 AccessKey:

  1. 在 RAM 用户详情页打开 认证管理AccessKey 标签
  2. 点击 创建 AccessKey,按提示完成安全校验
  3. 创建成功后立即复制保存:
    • AccessKey IDALIBABA_CLOUD_ACCESS_KEY_ID
    • AccessKey SecretALIBABA_CLOUD_ACCESS_KEY_SECRET

AccessKey Secret 只会在创建时显示一次。如果丢失,只能禁用旧密钥并重新创建。

如果你已经为手机号登录配置过同一个 RAM 用户的 AccessKey,直接复用即可,不要再为同一个用户创建多对 AccessKey。

切换 Storage Provider

packages/app-config/src/app-config.ts 中,把 common.storage.provider"r2" 改成 "aliyun-oss"

packages/app-config/src/app-config.ts
storage: {
  enabled: true,
  provider: "aliyun-oss", // 从 "r2" 改成 "aliyun-oss"
  publicPath: "/api/storage",
  // ...其余字段保持不变
},

切换后,所有 avatar / attachment 上传、下载、列举、删除都会自动走 OSS Provider,业务代码、上传组件、Better Auth 头像逻辑都不需要改。

填入本地与生产环境变量

本地开发写入 apps/server/.dev.vars

apps/server/.dev.vars
ALIBABA_CLOUD_ACCESS_KEY_ID=your-access-key-id
ALIBABA_CLOUD_ACCESS_KEY_SECRET=your-access-key-secret

ALIYUN_OSS_BUCKET=your-oss-bucket
ALIYUN_OSS_REGION=your-oss-region
ALIYUN_OSS_ENDPOINT=your-oss-endpoint

生产部署写入 apps/server/.env.production

apps/server/.env.production
ALIBABA_CLOUD_ACCESS_KEY_ID=your-access-key-id
ALIBABA_CLOUD_ACCESS_KEY_SECRET=your-access-key-secret

ALIYUN_OSS_BUCKET=your-oss-bucket
ALIYUN_OSS_REGION=your-oss-region
ALIYUN_OSS_ENDPOINT=your-oss-endpoint

切换到 OSS 后,R2_PUBLIC_URL 不再需要,可以从两个环境文件中删除。apps/server/wrangler.jsonc 中的 r2_buckets 绑定(STORAGE)也不再被读取,可以保留以便随时切回,也可以删除。

推送生产 Secrets

部署到 Cloudflare Workers 前,把生产密钥推送到 Workers Secrets:

pnpm -F server secrets:bulk:production

推送成功后,Worker 运行时通过 env.ALIBABA_CLOUD_ACCESS_KEY_IDenv.ALIBABA_CLOUD_ACCESS_KEY_SECRETenv.ALIYUN_OSS_BUCKETenv.ALIYUN_OSS_REGIONenv.ALIYUN_OSS_ENDPOINT 读取这些变量。更新任意一个值后重新执行这条命令即可生效,不需要因为 Secret 变化重新部署代码。

本地验证文件上传

启动服务端与客户端:

pnpm dev:server
pnpm dev:web

登录后在个人资料页上传一张头像。前端会向 /api/storage/upload 提交文件,服务端调用 OSS Provider 的 put 方法把文件写入 avatars/<userId>/...,并返回如下形式的公共 URL:

http://localhost:3001/api/storage/aliyun-oss/avatars/<userId>/<uuid>.png

后续读取由服务端的 /api/storage/aliyun-oss/<key> 路由代理回 OSS,Bucket 本身保持私有即可。

可以在 OSS 控制台的 文件管理 中确认对象已经写入对应前缀;在浏览器中直接打开上面那条公共 URL 也应该能看到图片。