使用自定义JWT及RLS时Supabase Realtime无事件触发的问题求助
自定义JWT结合RLS时Supabase实时数据无法触发问题
我在使用行级安全(RLS)和自定义JWT时,无法从Supabase数据库获取实时数据。普通查询数据库一切符合预期,但使用Realtime功能监听变更时,完全没有事件触发。
Astro框架代码实现
import { createClient } from "@supabase/supabase-js"; const supabase = await createClient(import.meta.env.PUBLIC_SUPABASE_URL, import.meta.env.PUBLIC_SUPABASE_KEY, { global: { headers: { Authorization: `Bearer ${jwt}`, }, }, }); supabase.from('notes').select().then(({data, error}) => { console.log(data, error) // 这里正常工作,控制台能输出我的notes数据 }) // 不确定这两行是否必要,查了大量资料后添加 supabase.realtime.setAuth(jwt) supabase.realtime.accessToken = jwt // 问题核心:当notes表发生更新时,控制台无任何输出 supabase .channel('notes') .on('postgres_changes', { event: '*', schema: '*', table: 'notes' }, payload => { console.log("检测到notes数据库变更:", payload) // 这条日志从未执行 }) .subscribe()
notes表RLS规则
(((current_setting('request.jwt.claims'::text, true))::json #>> '{email}'::text[]) IS NOT NULL)
疑问
这种失败看起来像是JWT不包含email字段,但为什么普通查询能正常工作?
自定义JWT生成代码(基于Jose库)
const signingSecret = import.meta.env.SUPABASE_JWT_SECRET; if (signingSecret) { session.supabaseAccessToken = await new jose.SignJWT({ email: user.email, role: "authenticated" }) .setProtectedHeader({ alg: 'HS256' }) .setAudience("authenticated") .setExpirationTime(Math.floor(new Date(session.expires).getTime() / 1000)) .setSubject(user.id) .sign(new TextEncoder().encode(signingSecret)) }
测试结果
- 使用
service_role用户可以正常看到实时更新; - 使用
anon_user用户无法看到实时更新。
补充信息
开发者工具网络标签显示WebSocket连接正常(能看到心跳和同步事件),但没有postgres事件传输。由于对数据库不熟悉,难以调试RLS策略,也没有便捷方式记录RLS策略失败的场景。
内容的提问来源于stack exchange,提问作者Andrew Bloyce
相关产品推荐
相关产品推荐

