启用RLS后,Supabase如何允许API更新用户Stripe客户ID?
解决Supabase启用RLS后无法更新Stripe客户ID的问题
方案一:使用服务端密钥绕过RLS(推荐)
你的NextJS API路由属于可信服务端操作,直接使用Supabase的service_role密钥初始化客户端,即可获得无限制的数据库操作权限,无需编写复杂的RLS策略。
步骤1:创建服务端专用Supabase客户端
在utils目录下新建supabaseServerClient.js:
import { createClient } from '@supabase/supabase-js'; export const supabaseServer = createClient( process.env.NEXT_PUBLIC_SUPABASE_URL, process.env.SUPABASE_SERVICE_ROLE_KEY // 此密钥需保密,绝不能暴露给前端 );
步骤2:修改API路由使用服务端客户端
替换原有API路由中的Supabase客户端:
import initStripe from "stripe"; import { supabaseServer } from "../../utils/supabaseServerClient"; const handler = async (req, res) => { if (req.query.API_ROUTE_SECRET !== process.env.API_ROUTE_SECRET) { return res.status(401).send('无权调用该API'); } const stripe = initStripe(process.env.STRIPE_SECRET_KEY); const customer = await stripe.customers.create({ email: req.body.record.email, }); await supabaseServer .from("profiles") .update({ stripe_customer: customer.id }) .eq("id", req.body.record.id); res.send({ message: `Stripe客户已创建:${customer.id}` }); }; export default handler;
方案二:编写RLS策略允许更新stripe_customer字段
若你需通过RLS实现,需创建针对性策略,但此方案存在一定安全风险,需谨慎使用。
步骤1:启用profiles表RLS
在Supabase控制台数据库 > 表中找到profiles表,开启行级安全。
步骤2:创建更新策略
在Supabase控制台数据库 > 策略中,为profiles表添加以下策略(或直接执行SQL):
-- 允许匿名用户更新指定用户的stripe_customer字段 CREATE POLICY "Allow setting stripe_customer via API" ON profiles FOR UPDATE TO anon USING (id = req.body.record.id) -- 匹配待更新的用户ID WITH CHECK ( -- 仅允许更新stripe_customer字段,且首次设置或修改 (new.stripe_customer IS NOT NULL) AND (old.stripe_customer IS NULL OR old.stripe_customer != new.stripe_customer) );
补充:添加用户自身访问策略
为确保普通用户只能访问自己的profile,需添加以下策略:
-- 允许登录用户查看自己的profile CREATE POLICY "Users can view their own profile" ON profiles FOR SELECT TO authenticated USING (id = auth.uid()); -- 允许登录用户更新自己的profile(可选) CREATE POLICY "Users can update their own profile" ON profiles FOR UPDATE TO authenticated USING (id = auth.uid());
内容的提问来源于stack exchange,提问作者Sam Donaghy-Bell
相关产品推荐
相关产品推荐

