[{"data":1,"prerenderedAt":342},["ShallowReactive",2],{"blog-zh-2026-03-01-tokyo-service-supabase":3},{"id":4,"title":5,"body":6,"category":323,"date":324,"description":325,"draft":326,"extension":327,"lang":328,"meta":329,"navigation":335,"path":336,"seo":337,"sitemap":338,"slug":339,"stem":340,"updated":324,"__hash__":341},"blog/blog/zh/2026-03-01-tokyo-service-supabase.md","Supabase Signup 失败：gen_random_bytes() does not exist",{"type":7,"value":8,"toc":309},"minimark",[9,14,18,29,32,42,46,52,56,59,62,65,68,72,79,90,93,97,102,157,161,206,210,213,222,229,233,236,247,250,258,262,265,276,284,288,291,305],[10,11,13],"h2",{"id":12},"问题现象","❗ 问题现象",[15,16,17],"p",{},"用户注册（Signup）失败，并出现错误：",[19,20,26],"pre",{"className":21,"code":23,"language":24,"meta":25},[22],"language-text","function gen_random_bytes(integer) does not exist\nNo function matches the given name and argument types\ncurrent transaction is aborted, commands ignored until end of transaction block\n","text","",[27,28,23],"code",{"__ignoreMap":25},[15,30,31],{},"表现为：",[33,34,35,39],"ul",{},[36,37,38],"li",{},"无法创建新用户",[36,40,41],{},"Supabase Auth 注册持续失败",[10,43,45],{"id":44},"触发流程","🔄 触发流程",[19,47,50],{"className":48,"code":49,"language":24,"meta":25},[22],"Client Signup\n  ↓\nauth.users INSERT\n  ↓\nAFTER INSERT Trigger\n  ↓\ncreate_profile_for_new_user()\n  ↓\ngen_random_bytes()\n",[27,51,49],{"__ignoreMap":25},[10,53,55],{"id":54},"原因分析","🔍 原因分析",[15,57,58],{},"gen_random_bytes() 并非 PostgreSQL core 内置函数，而是来自 pgcrypto 扩展，\n在 Supabase 中通常位于 extensions schema： extensions.gen_random_bytes()。",[15,60,61],{},"在 Supabase 中，用户注册后会触发：auth.users → trigger → 自定义函数，\n该函数通常使用：SECURITY DEFINER 。",[15,63,64],{},"此时 PostgreSQL 在 SECURITY DEFINER 函数中不会继承调用者的 search_path ，\n而是使用函数定义时的 search_path，导致：pgcrypto 提供的函数所在 schema 不可见。",[15,66,67],{},"因此数据库无法解析 gen_random_bytes() ，即使数据库中已安装 pgcrypto 扩展，\n由于 search_path 未包含 extensions schema，函数解析阶段仍会失败。",[10,69,71],{"id":70},"根本原因root-cause","🎯 根本原因（Root Cause）",[15,73,74,75,78],{},"Supabase Auth Trigger 通常使用 SECURITY DEFINER 执行。",[76,77],"br",{},"\n在该模式下：",[33,80,81,84,87],{},[36,82,83],{},"SECURITY DEFINER 函数会使用函数创建时记录的\nsearch_path，而不会继承调用者的 search_path",[36,85,86],{},"非默认 schema（如 extensions / pgcrypto）不可见",[36,88,89],{},"未显式指定 schema 的函数调用失败",[15,91,92],{},"因此问题并不在 Supabase Auth，而在 SECURITY DEFINER 函数的 schema 解析环境。\n问题发生在函数解析阶段（function lookup），而非扩展安装阶段。",[10,94,96],{"id":95},"解决方法","✅ 解决方法",[98,99,101],"h3",{"id":100},"显式-schema","显式 schema",[19,103,107],{"className":104,"code":105,"language":106,"meta":25,"style":25},"language-sql shiki shiki-themes github-light github-light github-dark","extensions.gen_random_bytes(16)\n-- or\npgcrypto.gen_random_bytes(16)\n","sql",[27,108,109,134,141],{"__ignoreMap":25},[110,111,114,118,122,125,128,131],"span",{"class":112,"line":113},"line",1,[110,115,117],{"class":116},"sBjJW","extensions",[110,119,121],{"class":120},"sxrX7",".",[110,123,124],{"class":116},"gen_random_bytes",[110,126,127],{"class":120},"(",[110,129,130],{"class":116},"16",[110,132,133],{"class":120},")\n",[110,135,137],{"class":112,"line":136},2,[110,138,140],{"class":139},"sCsY4","-- or\n",[110,142,144,147,149,151,153,155],{"class":112,"line":143},3,[110,145,146],{"class":116},"pgcrypto",[110,148,121],{"class":120},[110,150,124],{"class":116},[110,152,127],{"class":120},[110,154,130],{"class":116},[110,156,133],{"class":120},[98,158,160],{"id":159},"在-security-definer-函数中显式设置-search_path","在 SECURITY DEFINER 函数中显式设置 search_path",[19,162,164],{"className":104,"code":163,"language":106,"meta":25,"style":25},"CREATE OR REPLACE FUNCTION ...\nSECURITY DEFINER\nSET search_path = public, extensions\n",[27,165,166,184,192],{"__ignoreMap":25},[110,167,168,172,175,178,181],{"class":112,"line":113},[110,169,171],{"class":170},"s8jYJ","CREATE",[110,173,174],{"class":170}," OR",[110,176,177],{"class":170}," REPLACE",[110,179,180],{"class":170}," FUNCTION",[110,182,183],{"class":120}," ...\n",[110,185,186,189],{"class":112,"line":136},[110,187,188],{"class":170},"SECURITY",[110,190,191],{"class":120}," DEFINER\n",[110,193,194,197,200,203],{"class":112,"line":143},[110,195,196],{"class":170},"SET",[110,198,199],{"class":120}," search_path ",[110,201,202],{"class":170},"=",[110,204,205],{"class":120}," public, extensions\n",[98,207,209],{"id":208},"替代方案-random","替代方案 random()",[15,211,212],{},"可改用 PostgreSQL 内置函数：",[19,214,216],{"className":104,"code":215,"language":106,"meta":25,"style":25},"random()\n",[27,217,218],{"__ignoreMap":25},[110,219,220],{"class":112,"line":113},[110,221,215],{"class":120},[15,223,224,225,228],{},"⚠️ 注意：\n",[27,226,227],{},"random()"," 并非加密安全随机数，不应用于 token、handle 或任何安全相关场景。",[10,230,232],{"id":231},"️-最佳实践","🛡️ 最佳实践",[15,234,235],{},"Auth Trigger 中建议：",[33,237,238,241,244],{},[36,239,240],{},"避免依赖扩展函数",[36,242,243],{},"避免跨 schema 调用",[36,245,246],{},"避免复杂业务逻辑",[15,248,249],{},"Trigger 应仅负责：",[33,251,252,255],{},[36,253,254],{},"基础 INSERT",[36,256,257],{},"最小数据初始化",[10,259,261],{"id":260},"总结","📌 总结",[15,263,264],{},"gen_random_bytes() 报不存在，并非函数缺失，而是：",[33,266,267,270,273],{},[36,268,269],{},"SECURITY DEFINER 改变执行环境",[36,271,272],{},"search_path 未包含 extensions schema",[36,274,275],{},"pgcrypto 函数解析失败",[15,277,278,279,283],{},"本质上，这是 ",[280,281,282],"strong",{},"PostgreSQL schema 可见性问题，\n而非 Supabase Bug 或扩展安装问题","。",[10,285,287],{"id":286},"适用场景","📎 适用场景",[15,289,290],{},"本文适用于：",[33,292,293,296,299,302],{},[36,294,295],{},"Supabase Auth Trigger 报错",[36,297,298],{},"PostgreSQL SECURITY DEFINER 函数异常",[36,300,301],{},"pgcrypto 函数无法调用",[36,303,304],{},"Trigger 中扩展函数失效",[306,307,308],"style",{},"html pre.shiki code .sBjJW, html code.shiki .sBjJW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s8jYJ, html code.shiki .s8jYJ{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":25,"searchDepth":136,"depth":136,"links":310},[311,312,313,314,315,320,321,322],{"id":12,"depth":136,"text":13},{"id":44,"depth":136,"text":45},{"id":54,"depth":136,"text":55},{"id":70,"depth":136,"text":71},{"id":95,"depth":136,"text":96,"children":316},[317,318,319],{"id":100,"depth":143,"text":101},{"id":159,"depth":143,"text":160},{"id":208,"depth":143,"text":209},{"id":231,"depth":136,"text":232},{"id":260,"depth":136,"text":261},{"id":286,"depth":136,"text":287},"supabase","2026-03-01T00:00:00.000Z","Supabase Signup 报错 gen_random_bytes() does not exist 的真正原因：\nPostgreSQL SECURITY DEFINER 重置 search_path，\n导致 pgcrypto 函数不可访问。",false,"md","zh",{"tags":330},[323,331,332,146,333,334],"postgresql","trigger","security-definer","database-debug",true,"/blog/zh/2026-03-01-tokyo-service-supabase",{"title":5,"description":325},{"loc":336},null,"blog/zh/2026-03-01-tokyo-service-supabase","9z8ODVNBDdnS8k3_XXqVqc8NfGTUlvsKcbL_l68-XrY",1784966032071]