存储(Storage)

更新时间:
复制为 MD 格式

RDS Supabase存储服务通过存储桶、文件夹和文件三个核心概念来管理您的文件。

基本概念

  • 存储桶:存储文件的顶层容器,可以看作“超级文件夹”。通常,您会为不同的安全或访问规则创建独立的存储桶,例如,一个用于存放公开图片,另一个用于存放私有用户资料。

  • 文件夹:在存储桶内组织文件,用法与您计算机上的文件夹相同。

  • 文件:任何媒体文件,如图片、视频等。将这类大文件存放在存储服务中,可以减轻数据库的负担。请注意,出于安全原因,HTML文件将以纯文本形式提供。

重要

所有存储桶、文件夹和文件的名称都必须遵循阿里云OSS命名规范,避免使用特殊字符。

参数说明

RDS Supabase Storage默认集成了一个内置的阿里云 OSS 实例,开箱即用。同时,也支持连接到您自有的阿里云 OSS 或其他任何 S3 兼容的对象存储服务。若需使用自有存储,请在 RDS Supabase 实例详情页的Storage配置页面中配置以下参数。

S3兼容存储配置

参数名称

参数描述

格式要求与说明

GLOBAL_S3_ENDPOINT

OSS的访问域名

  • 必须为有效 URL,以 https:// 开头

  • 示例:https://oss-cn-beijing.aliyuncs.com

GLOBAL_S3_BUCKET

OSSBucket名称

  • 名称需符合所用S3服务的存储桶命名规范。

  • 示例:beijing-supabase-test

REGION

OSS的地域

  • 填写地域代码,全小写。

  • 示例: cn-beijing

TENANT_ID

OSS目录名称,无需创建

  • 建议使用 Supabase 项目ID

  • 示例:ra-supabase-xxx

AWS_ACCESS_KEY_ID

OSSAccessKey ID

  • 符合AK格式要求。

AWS_SECRET_ACCESS_KEY

OSSAccessKey Secret

  • 符合SK格式要求。

AWS_SESSION_TOKEN

(可选)OSS的临时访问令牌。

  • 仅在使用临时凭证 (如 STS) 时需要

  • 长期凭证场景下可省略

通用存储配置

参数名称

参数描述

格式要求与说明

FILE_SIZE_LIMIT

限制上传单个文件的最大体积,单位为字节。

  • 必须为正整数(单位:字节)

  • 示例:10485760(=10 MB)

文件存储

可以通过以下两种方式与存储服务进行交互:

  • RDS Supabase 控制台:提供图形化界面,适合进行手动的、可视化的文件管理操作。

  • RDS Supabase SDK:提供编程接口,适合在应用程序中以自动化的方式管理文件,例如用户上传文件、动态生成下载链接等。

通过RDS Supabase 控制台管理

RDS Supabase项目的控制台左侧边栏中,选择Storage即可进入存储管理界面。

1. 创建存储桶

首次使用时,存储界面是空的。首先需要创建一个存储桶bucket来存放文件。

  1. Storage页面,单击创建New bucket

  2. 在弹出的对话框中,输入存储桶名称

  3. 根据需要,决定是否将存储桶设为公开 (Public bucket)

    • 公开存储桶:桶内所有文件可通过URL直接公开访问,适合存放网站Logo、CSS 等公共资源。

    • 私有存储桶(默认):桶内文件需要授权才能访问,适合存放用户资料、订单信息等敏感数据。

  4. 单击Create完成创建。

image

2. 上传和管理文件

  1. 在存储桶列表中,单击目标存储桶进入其内部。

  2. 可以通过单击 创建文件夹 (Create folder) 来组织文件结构。

  3. 单击 上传文件 (Upload files),从本地选择一个或多个文件进行上传。

  4. 上传完成后,文件会显示在列表中。将鼠标悬停在文件上,单击右侧的 ... 菜单,可以执行下载 (Download)获取 URL (Get URL)移动 (Move)删除 (Delete) 等操作。

image

通过RDS Supabase SDK

使用官方的JavaScript客户端库 (@supabase/supabase-js) 可以方便地在应用中集成文件操作。下述以伪代码形式对文件操作进行说明。

1. 初始化客户端

在开始之前,确保已经安装了supabase-js 库,并使用项目URLServiceKey密钥初始化客户端。

import { createClient } from '@supabase/supabase-js';

// 从 Supabase 项目设置中获取 URL 和 ServiceKey
const supabaseUrl = 'YOUR_SUPABASE_URL';
const supabaseServiceKey = 'YOUR_SUPABASE_SERVICE_KEY';

const supabase = createClient(supabaseUrl, supabaseServiceKey);

2.创建存储桶

创建一个名为avatars的存储桶。

// Use the JS library to create a bucket.
const { data, error } = await supabase.storage.createBucket('avatars');

3.上传文件

avatars存储桶中上传一个文件。

const avatarFile = event.target.files[0];
const { data, error } = await supabase.storage
  .from('avatars')
  .upload('public/avatar1.png', avatarFile);

4.下载文件

avatars存储桶中下载指定文件。

// Use the JS library to download a file.
const { data, error } = await supabase.storage.from('avatars').download('public/avatar1.png');

完整操作示例代码如下:

示例代码

import { createClient } from "@supabase/supabase-js";

const supabaseUrl = "YOUR_SUPABASE_URL";
const supabaseKey = "YOUR_SUPABASE_SERVICE_KEY";

const supabase = createClient(supabaseUrl, supabaseKey);

// 为了演示,我们创建一个虚拟的文本文件
const content = 'Hello, Supabase Storage!';
const blob = new Blob([content], { type: 'text/plain' });
const fileName = `public/avatar-${Date.now()}.txt`;
const bucketName = 'avatars';

async function storageExample() {
  try {
    // 步骤 1: 创建一个新的存储桶 "avatars"
    // public: true 表示这是一个公开桶
    // 如果存储桶已存在,Supabase 会返回已存在的信息,不会报错
    const { data: bucketData, error: bucketError } = await supabase.storage.createBucket(
      bucketName,
      {
        public: true, // 设置为公开存储桶
      }
    );

    if (bucketError && bucketError.message !== 'The resource already exists') {
      throw new Error(`创建存储桶失败: ${bucketError.message}`);
    }
    console.log('存储桶创建或确认成功:', bucketData || '已存在');

    // 步骤 2: 上传文件到 "avatars" 存储桶
    const { data: uploadData, error: uploadError } = await supabase.storage
      .from(bucketName)
      .upload(fileName, blob, {
        cacheControl: '3600', // 缓存策略
        upsert: false // 如果文件已存在,则不覆盖
      });

    if (uploadError) {
      throw new Error(`文件上传失败: ${uploadError.message}`);
    }
    console.log('文件上传成功:', uploadData);

    // 步骤 3: 获取已上传文件的公开 URL
    const { data: urlData } = supabase.storage
      .from(bucketName)
      .getPublicUrl(fileName);

    console.log('文件的公开访问 URL:', urlData.publicUrl);

    // 其他操作示例:
    // 下载文件
    const { data: downloadData, error: downloadError } = await supabase.storage.from(bucketName).download(fileName);
    if (downloadError) {
      console.error('文件下载失败:', downloadError.message);
    } else {
      console.log('文件下载成功:', downloadData);
    }

    // 列出存储桶中的所有文件
    const { data: fileListData, error: fileListError } = await supabase.storage.from(bucketName).list();
    if (fileListError) {
      console.error('列出文件失败:', fileListError.message);
    } else {
      console.log('存储桶文件列表:', fileListData);
    }


  } catch (error) {
    console.error('存储操作出错:', error.message);
  }
}

// 执行示例函数
storageExample();

安全策略设置

RDS Storage Policies是基于PostgreSQL的行级安全(RLS)机制实现的存储访问控制策略,用于在数据库层面对存储对象的操作权限进行细粒度管控。

您可以通过RDS Supabase 控制台以下两种方式设置安全策略:

Policies页面手动设置

此方法通过图形化界面引导策略创建,无需编写复杂的 SQL,适合快速配置和大多数场景。

  1. RDS Supabase项目控制台的左侧导航栏中,选择Storage > Policies

  2. Policies页面存储桶列表中,单击New Policy

  3. 选择 Get a policy from a template 使用预设的存储模板,或选择Create a new policy from scratch进行完全自定义配置。

  4. 在策略配置页面,填写相关字段:

    • Policy name:为策略指定一个描述性名称,如 `Allow authenticated read access`。

    • Allowed operation:选择允许的操作,如 `SELECT` (下载/列出) 或 `INSERT` (上传)。

    • Target roles:选择此策略适用的角色,如 `authenticated`(已认证用户)。

    • Policy definition:定义读取、更新或删除时必须满足的条件。例如,`bucket_id = 'avatars'` 限制策略只对名为 `avatars` 的存储桶生效。

  5. 单击Review 检查生成的SQL语句,确认无误后单击Save policy完成创建。

image

通过SQL Editor设置

对于复杂场景或批量操作,可以直接在 SQL Editor 中执行 `CREATE POLICY` 语句来创建或修改策略。

示例 1:允许对指定存储桶的公共读取

此策略允许任何人读取 `avatars` 存储桶中的所有文件。

CREATE POLICY "Public read access for avatars"
ON storage.objects FOR SELECT
USING ( bucket_id = 'avatars' );

示例 2:仅允许认证用户访问自己的文件

此策略组合确保用户只能上传、查看、更新和删除其个人文件夹(路径为 `/*`)内的文件。

-- 允许认证用户在自己的文件夹内上传文件
CREATE POLICY "Allow authenticated uploads in user folder"
ON storage.objects FOR INSERT
TO authenticated
WITH CHECK(bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1]);

-- 允许认证用户读取自己文件夹内的文件
CREATE POLICY "Allow authenticated reads in user folder"
ON storage.objects FOR SELECT
TO authenticated
USING(bucket_id = 'avatars' AND auth.uid()::text = (storage.foldername(name))[1]);

更多安全策略设置请参考Supabase官方存储安全文档

相关API