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

Supabase行级安全(RLS)配置异常求助

RLS规则关联其他表返回空结果的排查与解决

问题描述

现有以下PostgreSQL数据表结构:

create table
  public.records (
    id uuid not null default gen_random_uuid (),
    created_at timestamp with time zone not null default now(),
    content text null,
    patient_id uuid null,
    provider_id uuid null,
    constraint records_pkey primary key (id),
    constraint records_patient_id_fkey foreign key (patient_id) references patient_profiles (id) on update cascade on delete cascade,
    constraint records_provider_id_fkey foreign key (provider_id) references provider_profiles (id) on update cascade on delete cascade
  ) tablespace pg_default;

create table
  public.provider_patient (
    id uuid not null default gen_random_uuid (),
    created_at timestamp with time zone not null default now(),
    provider_id uuid null,
    patient_id uuid null,
    constraint provides_care_to_pkey primary key (id),
    constraint provider_patient_patient_id_fkey foreign key (patient_id) references patient_profiles (id) on update cascade on delete cascade,
    constraint provider_patient_provider_id_fkey foreign key (provider_id) references provider_profiles (id) on update cascade on delete cascade
  ) tablespace pg_default;

create table
  public.provider_profiles (
    id uuid not null,
    first_name text null,
    last_name text null,
    phone text null,
    constraint provider_profiles_pkey primary key (id),
    constraint provider_profiles_id_fkey foreign key (id) references auth.users (id) on delete cascade
  ) tablespace pg_default;

create table
  public.patient_profiles (
    id uuid not null default gen_random_uuid (),
    created_at timestamp with time zone not null default now(),
    first_name text null,
    last_name text null,
    phone text null,
    email text null,
    constraint patients_pkey primary key (id)
  ) tablespace pg_default;

表关系:医护人员(provider)与患者是多对多关联;记录(records)属于单个患者,一个患者对应多条记录。

需求:配置RLS规则,让医护人员仅能查看自己负责的患者的记录。

测试情况:

  • 硬编码UUID的SQL查询可正常返回过滤后的记录:
SELECT
  *
FROM
  RECORDS
where
  'cec107e4-90bd-40e8-a233-d0b69a7d4c2c' in (
    select
      provider_id
    from
      provider_patient
    where
      patient_id = records.patient_id
  )
  • 转换为RLS规则后返回空结果,即使去掉WHERE子句测试仍为空:
(
  auth.uid () IN (
    SELECT
      provider_patient.provider_id
    FROM
      provider_patient
    WHERE
      (provider_patient.patient_id = records.patient_id)
  )
)

使用EXISTS语法编写规则,只要涉及其他表也始终返回空。

问题根源

  1. provider_patient表的RLS或权限未配置:RLS规则执行时,当前用户没有权限访问provider_patient表的行,导致子查询返回空。如果该表未开启RLS,普通用户可能默认没有SELECT权限;如果开启了RLS但未配置对应策略,也会被过滤所有行。
  2. 用户身份不匹配:当前登录用户的auth.uid()未在provider_profiles中注册为医护人员,或者provider_patient中没有该用户与患者的关联记录。
  3. records表未启用RLS:如果records表本身没有开启行级安全,配置的规则不会生效,但这里返回空更可能是其他表权限问题。

解决方案

1. 配置provider_patient表的访问权限

首先开启provider_patient的RLS:

ALTER TABLE public.provider_patient ENABLE ROW LEVEL SECURITY;

然后创建策略,允许医护人员查看自己的患者关联记录:

CREATE POLICY "Providers can access their patient links" ON public.provider_patient
FOR SELECT USING (provider_id = auth.uid());

如果需要支持新增/修改关联记录,可以补充对应的策略。

2. 创建正确的records表RLS规则

使用EXISTS语法编写更高效的查询规则,同时确保规则关联逻辑正确:

-- 先确保records表开启RLS
ALTER TABLE public.records ENABLE ROW LEVEL SECURITY;

-- 创建查询策略
CREATE POLICY "Providers can view their patients' records" ON public.records
FOR SELECT USING (
  EXISTS (
    SELECT 1 
    FROM public.provider_patient
    WHERE provider_patient.provider_id = auth.uid()
      AND provider_patient.patient_id = records.patient_id
  )
);

3. 验证关键条件

  • 确认当前登录用户的auth.uid()存在于provider_profiles.id中,即该用户已注册为医护人员。
  • 确认provider_patient表中存在该用户(provider_id)与对应患者(patient_id)的关联记录。
  • 直接执行SELECT * FROM provider_patient作为当前用户,验证是否能返回关联数据,以此确认provider_patient的权限配置正确。

额外排查技巧

如果去掉子查询的WHERE子句仍返回空,说明当前用户无法访问provider_patient的任何行。此时可以:

  • 检查provider_patient表的基础权限:执行GRANT SELECT ON public.provider_patient TO authenticated;(如果用户属于authenticated角色),或者通过RLS策略开放权限。
  • 验证auth.uid()的返回值:执行SELECT auth.uid();确认当前用户的UUID,与provider_patient.provider_id中的值做比对。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 06:00:30