如何通过hCaptcha验证为Supabase的ratings表设置插入权限?
解决Supabase匿名用户hCaptcha验证的RLS权限问题
1. 前提准备
首先确保你的Supabase项目已启用http扩展(用于调用hCaptcha验证API),在SQL编辑器执行:
CREATE EXTENSION IF NOT EXISTS http;
同时确保ratings表已开启行级安全(RLS):
ALTER TABLE ratings ENABLE ROW LEVEL SECURITY;
2. 修正hCaptcha验证函数
你遇到的supabase.headers()未定义问题,是因为Supabase中获取请求头的正确方式为current_setting('request.headers'),以下是修正后的验证函数:
CREATE OR REPLACE FUNCTION hcaptcha_verified() RETURNS boolean AS $$ DECLARE request_headers jsonb; hcaptcha_response text; api_response jsonb; hcaptcha_secret text := current_setting('app.hcaptcha_secret'); -- 从环境变量读取密钥 BEGIN -- 获取请求头数据 request_headers := current_setting('request.headers', true)::jsonb; hcaptcha_response := request_headers->>'x-hcaptcha-response'; -- 无hCaptcha响应直接返回验证失败 IF hcaptcha_response IS NULL OR hcaptcha_response = '' THEN RETURN false; END IF; -- 调用hCaptcha官方验证接口 api_response := http_post( 'https://hcaptcha.com/siteverify', 'application/x-www-form-urlencoded', 'secret=' || urlencode(hcaptcha_secret) || '&response=' || urlencode(hcaptcha_response) ).content::jsonb; -- 返回验证结果 RETURN api_response->>'success'::boolean; END; $$ LANGUAGE plpgsql SECURITY DEFINER;
关键说明:
- 用
current_setting('request.headers', true)获取请求头,第二个参数true确保无该设置时返回NULL而非报错 - 从Supabase环境变量
app.hcaptcha_secret读取密钥(避免硬编码泄露风险),需在Supabase控制台「设置」→「API」→「环境变量」中添加该变量 - 使用
urlencode()对参数编码,防止拼接时出现格式错误 - 增加空值判断,避免因缺少请求头导致的异常
3. 创建RLS插入策略
为ratings表创建匿名用户插入策略,仅当hCaptcha验证通过时允许操作:
CREATE POLICY "Allow anonymous insert after hCaptcha verification" ON ratings FOR INSERT TO anon USING (hcaptcha_verified());
4. 客户端调用注意事项
客户端插入数据时,需将hCaptcha的响应值放入请求头x-hcaptcha-response中。以Supabase JS客户端为例:
const { data, error } = await supabase .from('ratings') .insert([{ rating: 5, review: '体验很好', name: '匿名用户' }]) .headers({ 'x-hcaptcha-response': '用户完成hCaptcha后获取的响应字符串' });
内容的提问来源于stack exchange,提问作者Amirhosein Nikfallah
相关产品推荐
相关产品推荐

