Supabase插入数据违反行级安全策略错误排查求助
问题:插入
user_profiles表时触发行级安全策略错误 当尝试向user_profiles表插入新行时,出现错误:"New row violates row-level security policy for table"。该表存在指向auth.users.id的外键user_id。
我通过supabase.auth.onAuthStateChange钩子,期望在用户登录时自动插入新行。最初启用RLS(行级安全)但未配置任何策略,之后尝试添加仅允许认证用户插入行的模板策略,问题未解决;参考相关内容添加认证用户查询的模板策略后,仍报相同错误。
认证逻辑在Chrome浏览器扩展的后台脚本中实现,相关代码如下:
supabase.ts
import { createClient } from '@supabase/supabase-js' import qs from 'qs' const supaUrl = import.meta.env.VITE_SUPABASE_URL const supaANONKey = import.meta.env.VITE_SUPABASE_ANON_KEY export const supabase = createClient(supaUrl, supaANONKey, { global: { fetch: (...args) => fetch(...args), }, }) export const extensionSupabaseLogin = async () => { const redirectUri = chrome.identity.getRedirectURL('supabase-auth') const options = { provider: 'notion', redirect_to: redirectUri, ux_mode: 'redirect', } const url = `${supaUrl}/auth/v1/authorize?${qs.stringify(options)}` const originalTab = (await chrome.tabs.query({ active: true, currentWindow: true }))[0] const authenticationTab = await chrome.tabs.create({ url: 'about:blank' }) chrome.tabs.onUpdated.addListener(function notionAuthHook(tabId, _changeInfo, tab) { if (tabId === authenticationTab.id && tab.url?.startsWith(redirectUri)) { const splitUrl = tab.url?.split('#')[1] // 解析失败时提示用户重新登录(错误情况) if (!splitUrl) { console.error('无法解析登录URL', tab.url) return } // 从URL中解析令牌 const authResult = qs.parse(splitUrl) const refreshToken = authResult.refresh_token as string const accessToken = authResult.access_token as string // 无access_token时提示用户重新登录(错误情况) if (!refreshToken || !accessToken) { console.error('未返回access token或refresh token', authResult) return } ;(async () => { const { error } = await supabase.auth.setSession({ access_token: accessToken, refresh_token: refreshToken, }) if (error) console.error(error) })() chrome.tabs.onUpdated.removeListener(notionAuthHook) chrome.tabs.remove(tabId) if (originalTab?.id) { chrome.tabs.update(originalTab.id, { active: true }) } } }) // 引导用户进入登录流程 if (authenticationTab.id) { await chrome.tabs.update(authenticationTab.id, { url: url }) } }
background.ts
import { Client } from '@notionhq/client' import { extensionSupabaseLogin, supabase } from './supabase' chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'signIn') { extensionSupabaseLogin(); } else if (request.type === 'GET_NOTION_PAGE') { const { accessToken, ...options } = request.options as GetPageNotionOptions debugger if (!notionClient) { setNotionClient(accessToken) } if (notionClient) { const response = await notionClient.pages.retrieve({ ...options }) sendResponse({ type: 'SUCCESS', data: JSON.stringify(response) }) } } }); let notionClient: Client | null = null const setNotionClient = (notionCode: string) => { notionClient = new Client({ auth: notionCode, }) } const storeNotionIdentity = async (notionIdentity: { accessToken: string; refreshToken?: string }): Promise<void> => { setNotionClient(notionIdentity.accessToken) await chrome.storage.local.set({ notionIdentity, }) } const storeNotionUser = async (user: User): Promise<void> => { await chrome.storage.local.set({ user, }) } const setupAuthListener = () => { supabase.auth.onAuthStateChange(async (event, session) => { if (event === 'SIGNED_IN' || event === 'USER_UPDATED') { // 用户刚登录或会话已更新 console.log('用户已登录 :', session) if (session?.access_token && session?.refresh_token) { debugger await storeNotionIdentity({ accessToken: session.access_token, refreshToken: session.refresh_token }) } if (session?.user) { await storeNotionUser({ name: session.user.user_metadata?.name, fullName: session.user.user_metadata?.full_name, email: session.user?.email ?? session.user.user_metadata?.email, userId: session.user.id, }) } if (typeof loginTabId === 'number') { chrome.tabs.sendMessage(loginTabId, `notion登录成功`) } } else if (event === 'SIGNED_OUT') { // 用户刚登出或账号已被删除 console.log('用户已登出') loginTabId = null await chrome.storage.local.remove(['notionIdentity', 'user']) } }) } setupAuthListener()
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

