You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Supabase加密列通过API插入字符串存/取异常求助

问题分析与解决方案

你的问题核心是Supabase加密列通过API插入后无法正常解密,而仪表盘手动操作完全正常,这通常和API调用时的权限逻辑、SDK处理机制或加密触发条件有关,以下是几个可直接落地的排查和解决方向:

1. 验证RLS策略权限

加密列的自动加密依赖Supabase内部加密函数的执行,需确保customers表的RLS策略没有限制API调用时的加密操作:

  • 检查现有RLS策略,确保INSERT/UPSERT权限中允许加密列的写入逻辑,比如调整策略为:
    CREATE POLICY "允许认证用户更新客户数据" ON customers
    FOR UPSERT TO authenticated
    USING (auth.uid() = user_id) -- 根据你的实际权限规则调整
    WITH CHECK (true);
    
    过于严格的策略会阻止Supabase自动调用加密函数,导致数据未按预期加密存储。

2. 用普通INSERT替代UPSERT测试

先暂时替换upsert为insert验证加密逻辑是否正常:

async function createRowInTable(tableName, rowData) {
  try {
    const { data: result, error } = await supabase
      .from(tableName)
      .insert(rowData);

    if (error) {
      throw new Error(`插入数据失败 ${tableName}:`, error);
    }

    return result;
  } catch (err) {
    throw new Error('createRowInTable 异常:', err);
  }
}

如果insert操作后解密视图正常,说明upsert的onConflict参数可能干扰了加密触发,可尝试显式指定更新列:

.upsert(rowData, { onConflict: 'id', update: ['api_key'] })

3. 升级Supabase JS SDK到最新版

旧版本SDK可能存在加密列自动处理的bug,执行升级命令:

npm install @supabase/supabase-js@latest

4. 手动调用加密函数插入

如果自动加密仍不生效,可直接调用Supabase的加密函数手动处理数据:

async function saveCustomer(customerId, accessToken) {
  try {
    // 调用Supabase内置加密RPC函数
    const { data: encryptedKey, error } = await supabase.rpc('encrypt_string', {
      plaintext: accessToken,
      key_id: '你的密钥ID' // 替换为你在Supabase中配置的加密密钥ID
    });

    if (error) throw error;

    const customerData = {
      id: customerId,
      api_key: encryptedKey
    };

    await createRowInTable('customers', customerData, 'id');
  } catch (error) {
    throw new Error('saveCustomer 异常:', error);
  }
}

也可以在插入语句中直接使用加密表达式:

async function createRowInTable(tableName, rowData, conflictField) {
  try {
    const { data: result, error } = await supabase
      .from(tableName)
      .upsert({
        ...rowData,
        api_key: supabase.sql`crypto_secretbox_easy(${rowData.api_key}, '你的随机数', '你的密钥')`
      }, { onConflict: conflictField });

    if (error) {
      throw new Error(`插入数据失败 ${tableName}:`, error);
    }

    return result;
  } catch (err) {
    throw new Error('createRowInTable 异常:', err);
  }
}

注意:随机数(nonce)和密钥需与你创建加密列时使用的配置一致。

5. 核对加密列配置

确认api_key列是通过Supabase仪表盘创建的官方加密列,使用的是Supabase支持的加密方案(如pgsodium),而非手动添加的自定义加密逻辑,确保API与仪表盘使用的加密规则完全匹配。


内容的提问来源于stack exchange,提问作者Alex S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 16:13:24