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

NextJS中Supabase RLS策略失效问题求助

问题解决:Supabase RLS关联查询无结果

问题背景

使用包含user_profile、stripe_customer、subscription的关联数据模型,在Next.js的getServerSideProps中执行以下查询:

const { data, error } = await supabase.from('user_profile').select(`
        subscription ( status )
    `)
    .eq('user_id', session.user.id);

现有RLS配置:

  • user_profile表:auth.uid() = user_id
  • stripe_customer表:auth.uid() = user_id
  • subscription表:
(auth.uid() = ( SELECT stripe_customer.user_id
   FROM stripe_customer
  WHERE (stripe_customer.id = subscription.stripe_customer_id)))

执行查询无结果,关闭subscription表RLS后正常返回;尝试将subscription表RLS改为auth.uid() <> NULL::uuid或auth.uid() = NULL::uuid,同样无记录返回。

核心问题

1. 关联RLS的权限链断裂

从user_profile关联查询subscription时,subscription的RLS规则依赖stripe_customer表的子查询,但stripe_customer自身的RLS规则auth.uid() = user_id会限制该子查询的结果——子查询执行时,上下文是subscription行,无法自动继承当前用户的权限上下文,导致子查询无法匹配到stripe_customer记录,最终subscription的RLS判断为false,所有行被过滤。

2. NULL比较逻辑错误

SQL中NULL是特殊值,不能用=或<>进行比较,auth.uid() = NULL::uuid和auth.uid() <> NULL::uuid永远返回false,自然不会返回任何记录。正确的NULL判断应该用IS NULL或IS NOT NULL。

修复方案

修改subscription表的RLS策略

使用EXISTS子查询明确关联stripe_customer并验证用户权限,确保子查询能通过stripe_customer的RLS校验:

EXISTS (
  SELECT 1
  FROM stripe_customer sc
  WHERE sc.id = subscription.stripe_customer_id
  AND sc.user_id = auth.uid()
)

该写法会先验证stripe_customer中存在匹配当前用户且与subscription关联的记录,同时满足stripe_customer的RLS规则。

验证用户上下文

在getServerSideProps中确认supabase客户端已正确初始化并携带用户session,可通过打印auth.uid()验证当前用户ID是否与session.user.id一致。

数据关联校验

检查stripe_customer表中是否存在与当前用户user_id匹配的记录,且该记录的id与subscription表的stripe_customer_id对应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 01:42:04