Supabase登录后getSession返回null,插入数据触发RLS政策报错求助
问题与解决方案
问题详情
编写脚本以管理员身份爬取网页数据并插入Supabase数据库,要求仅特定邮箱用户能向stories表插入记录。当前登录、登出功能正常,但存在以下问题:
- 登录后调用
supabase.auth.getSession()返回session: null - 插入操作触发RLS错误:
new row violates row-level security policy for table "stories"(错误码42501) - 切换为允许所有匿名用户插入的RLS政策时,插入操作正常;应用仅允许特定邮箱用户的政策则失败。
用户代码如下:
const { data, error } = await supabase.auth.signInWithPassword({ // 以管理员用户身份登录 email: 'myemail@gmail.com', password: '*********', }) console.log('login data', data) // 打印所有会话和用户对象 console.log('login error', error) // 打印null if (!error && data.session?.access_token && data.session?.refresh_token) { const { data: setSessionData, error: setSessionError } = await supabase.auth.setSession({ access_token: data.session?.access_token, refresh_token: data.session?.refresh_token, }) console.log('last session', await supabase.auth.getSession()) // 打印 'last session { data: { session: null }, error: null }' } const { error: insertError } = await supabase.from('stories').insert([record]) // record是此代码上方已创建的对象 console.log('error', insertError) /* 打印 'error { code: '42501', details: null, hint: null, message: 'new row violates row-level security policy for table "stories"' } */ const { error: logutError } = await supabase.auth.signOut() console.log('logutError', logutError) // 打印 'logutError null' 表示功能正常
RLS插入政策说明:仅允许邮箱为myemail@gmail.com的认证用户向stories表插入记录。
问题原因
- 多余的
setSession调用:signInWithPassword成功后,Supabase客户端会自动存储会话信息,手动调用setSession会覆盖或破坏现有会话状态,导致getSession()无法正确获取会话。 - 会话未正确绑定:会话状态异常导致数据库RLS验证时无法识别当前登录用户,因此触发权限拒绝。
解决方案
1. 移除手动setSession调用
删除代码中手动设置会话的逻辑,直接使用signInWithPassword返回的会话状态:
const { data, error } = await supabase.auth.signInWithPassword({ email: 'myemail@gmail.com', password: '*********', }) console.log('login data', data) console.log('login error', error) // 直接获取当前会话,无需手动setSession const currentSession = await supabase.auth.getSession() console.log('current session', currentSession) if (!error && currentSession.data.session) { const { error: insertError } = await supabase.from('stories').insert([record]) console.log('insert error', insertError) } const { error: logoutError } = await supabase.auth.signOut() console.log('logout error', logoutError)
2. 验证RLS政策正确性
确保RLS政策的条件准确匹配管理员邮箱,示例政策SQL:
-- 启用表RLS(若未启用) ALTER TABLE stories ENABLE ROW LEVEL SECURITY; -- 创建仅允许指定邮箱用户插入的政策 CREATE POLICY "Admin only insert" ON stories FOR INSERT TO authenticated WITH CHECK (auth.email() = 'myemail@gmail.com');
3. 额外检查点
- 确认管理员用户邮箱与政策中的邮箱完全一致,无拼写错误。
- 若在服务器端运行脚本,确保Supabase客户端配置正确(
signInWithPassword可正常工作)。
内容的提问来源于stack exchange,提问作者Piyush Chauhan
相关产品推荐
相关产品推荐

