Supabase Signup 失败:gen_random_bytes() does not exist
Supabase Signup 报错 gen_random_bytes() does not exist 的真正原因: PostgreSQL SECURITY DEFINER 重置 search_path, 导致 pgcrypto 函数不可访问。
❗ 问题现象
用户注册(Signup)失败,并出现错误:
function gen_random_bytes(integer) does not exist
No function matches the given name and argument types
current transaction is aborted, commands ignored until end of transaction block
表现为:
- 无法创建新用户
- Supabase Auth 注册持续失败
🔄 触发流程
Client Signup
↓
auth.users INSERT
↓
AFTER INSERT Trigger
↓
create_profile_for_new_user()
↓
gen_random_bytes()
🔍 原因分析
gen_random_bytes() 并非 PostgreSQL core 内置函数,而是来自 pgcrypto 扩展, 在 Supabase 中通常位于 extensions schema: extensions.gen_random_bytes()。
在 Supabase 中,用户注册后会触发:auth.users → trigger → 自定义函数, 该函数通常使用:SECURITY DEFINER 。
此时 PostgreSQL 在 SECURITY DEFINER 函数中不会继承调用者的 search_path , 而是使用函数定义时的 search_path,导致:pgcrypto 提供的函数所在 schema 不可见。
因此数据库无法解析 gen_random_bytes() ,即使数据库中已安装 pgcrypto 扩展, 由于 search_path 未包含 extensions schema,函数解析阶段仍会失败。
🎯 根本原因(Root Cause)
Supabase Auth Trigger 通常使用 SECURITY DEFINER 执行。
在该模式下:
- SECURITY DEFINER 函数会使用函数创建时记录的 search_path,而不会继承调用者的 search_path
- 非默认 schema(如 extensions / pgcrypto)不可见
- 未显式指定 schema 的函数调用失败
因此问题并不在 Supabase Auth,而在 SECURITY DEFINER 函数的 schema 解析环境。 问题发生在函数解析阶段(function lookup),而非扩展安装阶段。
✅ 解决方法
显式 schema
extensions.gen_random_bytes(16)
-- or
pgcrypto.gen_random_bytes(16)
在 SECURITY DEFINER 函数中显式设置 search_path:
CREATE OR REPLACE FUNCTION ...
SECURITY DEFINER
SET search_path = public, extensions
替代方案 random()
可改用 PostgreSQL 内置函数:
random()
⚠️ 注意:
random() 并非加密安全随机数,不应用于 token、handle 或任何安全相关场景。
🛡️ 最佳实践
Auth Trigger 中建议:
- 避免依赖扩展函数
- 避免跨 schema 调用
- 避免复杂业务逻辑
Trigger 应仅负责:
- 基础 INSERT
- 最小数据初始化
📌 总结
gen_random_bytes() 报不存在,并非函数缺失,而是:
- SECURITY DEFINER 改变执行环境
- search_path 未包含 extensions schema
- pgcrypto 函数解析失败
本质上,这是 PostgreSQL schema 可见性问题, 而非 Supabase Bug 或扩展安装问题。
📎 适用场景
本文适用于:
- Supabase Auth Trigger 报错
- PostgreSQL SECURITY DEFINER 函数异常
- pgcrypto 函数无法调用
- Trigger 中扩展函数失效