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

Supabase权限配置问题:仅认证用户上传文件遇401错误

问题分析:Supabase存储上传时的401 JWT错误

问题场景

我希望存储桶内的文件对所有用户开放访问,但仅允许已认证用户执行上传操作。执行以下代码时出现错误:

await supabase.auth.setSession({
    access_token: session.access_token,
    refresh_token: session.refresh_token
});
const { data, error } = await supabase.storage
    .from('card-pictures')
    .upload(`/${cardPicture.toString()}`, cardPicture);

错误信息

{
  "statusCode": "401",
  "error": "Invalid JWT",
  "message": "new row violates row-level security policy for table \"objects\""
}

已知条件

  • 已打印确认当前处于认证状态
  • 配置了存储桶的认证用户访问策略,以及objects表的认证用户上传策略
  • 开放所有用户上传时功能正常

可能的原因及解决办法

1. JWT令牌已过期或失效

虽然你打印了session,但手动传入的access_token可能已经过期。setSession不会自动刷新过期令牌,建议改用refreshSession()获取有效令牌后再执行上传:

const { data: refreshedSession, error: refreshError } = await supabase.auth.refreshSession();
if (!refreshError) {
  const { data, uploadError } = await supabase.storage
    .from('card-pictures')
    .upload(`/${cardPicture.toString()}`, cardPicture);
}

2. RLS策略条件设置有误

检查objects表的上传策略是否正确关联认证用户。正确的策略需要明确限定认证用户身份,比如:

CREATE POLICY "认证用户可上传文件" ON storage.objects
FOR INSERT TO authenticated
WITH CHECK (bucket_id = 'card-pictures' AND auth.uid() = owner);

注意:如果策略未指定bucket_id,或者auth.uid()与owner字段的关联逻辑错误,会导致RLS拦截请求。

3. 存储桶与objects表策略冲突

确保存储桶策略和objects表策略逻辑对齐:

  • 存储桶读取策略(开放所有用户访问):
    CREATE POLICY "公开读取存储桶" ON storage.buckets
    FOR SELECT USING (name = 'card-pictures');
    
  • 存储桶写入策略(仅认证用户操作):
    CREATE POLICY "认证用户可操作存储桶" ON storage.buckets
    FOR INSERT, UPDATE, DELETE TO authenticated
    USING (name = 'card-pictures');
    

如果存储桶策略允许写入,但objects表策略未同步限定,会出现权限不匹配的情况。

4. 手动设置session的令牌不是最新值

手动保存并复用的session可能不是最新状态(比如令牌已被Supabase后台刷新)。建议依赖Supabase客户端自动管理会话,不要手动调用setSession传入旧令牌。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 03:22:44