启用RLS后无法通过Supabase的auth.uid作为外键查询app_users表
启用RLS后无法通过Supabase的auth.uid作为外键查询app_users表
嘿,我看你遇到的问题是开启RLS后,明明数据库里有对应认证用户的数据,却查不到,关掉RLS就正常对吧?我来帮你排查下问题~
首先,你的RLS策略写得有问题哦!你现在的策略是:
alter policy "Enable users to view their own data only" on "public"."app_users" to authenticated using ( true );
这里的using (true)相当于给所有认证用户开放了整个app_users表的访问权限,完全没做到“只看自己的数据”的限制。但就算是这样,按道理应该能查到数据才对,不过大概率是这个策略逻辑不对导致的权限异常。
你需要把策略改成真正限制用户只能访问自己的数据,也就是让表中的auth_id等于当前认证用户的uid,修改后的SQL应该是这样:
alter policy "Enable users to view their own data only" on "public"."app_users" to authenticated using (auth_id = auth.uid());
这里要注意一个细节:如果你的app_users表中auth_id字段类型是text而不是uuid,那得做个类型转换,改成:
using (auth_id = auth.uid()::text);
或者把auth_id转成uuid类型:
using (auth_id::uuid = auth.uid());
接下来,再检查下你的Flutter代码:
- 你用了
.single()来获取数据,如果查询不到结果会直接抛出异常,建议换成.maybeSingle(),这样查不到的时候会返回null,方便你调试,不会直接崩溃:
var appUser = await client .from("app_users") .select() .eq('auth_id', user.id) .limit(1) .maybeSingle();
- 确认下
user.id和数据库里的auth_id完全一致,可以在登录后打印一下user.id,再去数据库里核对对应的auth_id值,避免出现大小写或者字符不一致的情况。
最后,你可以在Supabase的SQL编辑器里测试RLS策略是否生效:
先切换到认证用户角色:
set role authenticated;
然后执行查询:
select * from app_users where auth_id = auth.uid();
如果这里能查到数据,说明策略没问题,那问题就出在Flutter代码的认证或者查询环节;如果查不到,那就是策略或者数据匹配的问题。
按照上面的步骤调整后,应该就能正常查到自己的数据啦~
内容来源于stack exchange
相关产品推荐
相关产品推荐

