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

Supabase触发器函数权限问题:触发器调用函数时访问被拒绝

解决Supabase触发器调用函数时的权限拒绝问题

问题原因

PostgreSQL函数默认采用SECURITY INVOKER执行模式,即函数会以调用者的权限运行。你的触发器由supabase_auth_admin用户触发,因此public.handle_new_user()会以该用户的权限执行操作:

  • supabase_auth_admin没有public.profiles表的插入权限,也没有调用public.insert_into_profiles()函数的足够权限
  • 你直接执行函数时用的是postgres用户(Supabase的超级用户),拥有所有操作权限,因此不会出现权限问题

解决方案

将public.handle_new_user()或public.insert_into_profiles()设置为SECURITY DEFINER模式,让函数以其拥有者的权限执行(默认拥有者是postgres,具备所需权限)。同时需要设置安全的搜索路径,避免SQL注入风险。

修改handle_new_user()函数

DROP TRIGGER IF EXISTS on_auth_user_created ON auth.users;

CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS TRIGGER AS $$
BEGIN
    RAISE LOG 'Current user: %', current_user;

    PERFORM public.insert_into_profiles(
        NEW.id,
        (NEW.raw_user_meta_data->>'first_name'),
        (NEW.raw_user_meta_data->>'last_name')      
    );

    RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER
SET search_path = public; -- 限制搜索路径,提升安全性

CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW
EXECUTE FUNCTION public.handle_new_user();

(可选)修改insert_into_profiles()函数

如果不想修改触发器函数,也可以直接调整insert_into_profiles()的执行模式:

CREATE OR REPLACE FUNCTION public.insert_into_profiles(user_id uuid, first_name text, last_name text)
RETURNS void AS $$
BEGIN
    INSERT INTO public.profiles(id, first_name, last_name)
    VALUES(user_id, first_name, last_name);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER
SET search_path = public;

额外验证

修改完成后,创建新用户触发触发器,检查public.profiles表是否成功插入数据,同时查看日志确认函数执行的用户已切换为函数拥有者(postgres)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:32:51