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
相关产品推荐
相关产品推荐

