Supabase安全:如何在JS SDK中使用JWT令牌并关闭公共访问?
解决Supabase安全问题:启用RLS并使用JWT认证访问数据
先搞懂那个警告的意思
你看到的WARNING : This table is publicly readable and writable. Enable Row Level Security,直白说就是你的表现在完全对外开放——任何人只要拿到你的匿名API密钥,就能随便读、改、删表里的所有数据,这是极大的安全风险。Row Level Security(RLS,行级安全)是Supabase用来精准控制数据访问权限的机制,必须开启。
第一步:关闭公共访问,启用RLS并配置权限
- 打开Supabase控制台,进入目标表的编辑器页面,打开Enable Row Level Security开关。
- 进入SQL编辑器,执行以下命令彻底关闭匿名访问(替换
your_table_name为你的表名):
执行后,只有通过Supabase认证的用户(持有有效JWT令牌)才能操作该表,匿名密钥彻底失去作用。-- 撤销匿名用户对表的所有操作权限 REVOKE ALL ON your_table_name FROM anon; -- 给已认证用户分配必要权限(根据业务需求调整SELECT/INSERT/UPDATE/DELETE) GRANT SELECT, INSERT, UPDATE, DELETE ON your_table_name TO authenticated;
第二步:在React的Supabase JS SDK中使用JWT(SDK自动处理,无需手动传令牌)
Supabase JS SDK会自动管理认证后的JWT会话,你只需要按正常流程做用户认证即可:
初始化Supabase客户端(依然需要匿名密钥,但它现在仅用于发起认证请求,无数据操作权限):
import { createClient } from '@supabase/supabase-js'; const supabaseUrl = '你的Supabase项目URL'; const supabaseAnonKey = '你的匿名API密钥'; export const supabase = createClient(supabaseUrl, supabaseAnonKey);用户登录/注册(以邮箱密码为例):
const handleLogin = async (email, password) => { const { data, error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) { console.error('登录失败:', error); return; } // 登录成功后,SDK自动把JWT令牌存在本地存储,后续请求会自动带上 console.log('登录成功,会话信息:', data.session); };执行数据库操作(请求自动携带JWT,仅符合RLS规则的操作会成功):
const fetchUserData = async () => { const { data, error } = await supabase .from('your_table_name') .select('*'); if (error) { console.error('获取数据失败:', error); // 未认证的请求会返回权限不足错误,这是正常的安全拦截 } else { console.log('获取到的数据:', data); } };如需手动获取JWT(比如自定义请求):
const { data: { session } } = await supabase.auth.getSession(); if (session) { const jwtToken = session.access_token; // 手动请求时在headers里加:Authorization: Bearer ${jwtToken} }
额外:配置精细化RLS规则(必做)
启用RLS后,建议给表添加具体规则,比如让用户只能访问自己的数据:
-- 用户只能查看自己的数据(假设表中有user_id字段存储用户ID) CREATE POLICY "用户仅能查看自身数据" ON your_table_name FOR SELECT USING (auth.uid() = user_id); -- 用户只能修改自己的数据 CREATE POLICY "用户仅能修改自身数据" ON your_table_name FOR UPDATE USING (auth.uid() = user_id);
auth.uid()会从JWT令牌中解析当前用户的ID,和表中字段匹配,确保数据访问的精准性。
内容的提问来源于stack exchange,提问作者Alvin
相关产品推荐
相关产品推荐

