supabase-rls

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Supabase Row Level Security (RLS)

Supabase行级安全(RLS)

Enable RLS on Table

为数据表启用RLS

sql
-- Always enable RLS
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
sql
-- Always enable RLS
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;

Common Policy Patterns

常见策略模式

User Can Only See Own Data

用户仅能查看自身数据

sql
CREATE POLICY "Users view own data"
ON projects FOR SELECT
TO authenticated
USING (auth.uid() = user_id);
sql
CREATE POLICY "Users view own data"
ON projects FOR SELECT
TO authenticated
USING (auth.uid() = user_id);

User Can Insert Own Data

用户仅能插入自身数据

sql
CREATE POLICY "Users insert own data"
ON projects FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);
sql
CREATE POLICY "Users insert own data"
ON projects FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);

User Can Update Own Data

用户仅能更新自身数据

sql
CREATE POLICY "Users update own data"
ON projects FOR UPDATE
TO authenticated
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
sql
CREATE POLICY "Users update own data"
ON projects FOR UPDATE
TO authenticated
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);

User Can Delete Own Data

用户仅能删除自身数据

sql
CREATE POLICY "Users delete own data"
ON projects FOR DELETE
TO authenticated
USING (auth.uid() = user_id);
sql
CREATE POLICY "Users delete own data"
ON projects FOR DELETE
TO authenticated
USING (auth.uid() = user_id);

Multi-Tenant Patterns

多租户模式

Team-Based Access

基于团队的访问

sql
-- Users can see projects in their teams
CREATE POLICY "Team members view projects"
ON projects FOR SELECT
TO authenticated
USING (
  team_id IN (
    SELECT team_id FROM team_members
    WHERE user_id = auth.uid()
  )
);
sql
-- Users can see projects in their teams
CREATE POLICY "Team members view projects"
ON projects FOR SELECT
TO authenticated
USING (
  team_id IN (
    SELECT team_id FROM team_members
    WHERE user_id = auth.uid()
  )
);

Role-Based Access

基于角色的访问

sql
-- Check user role for admin access
CREATE POLICY "Admins can do everything"
ON projects FOR ALL
TO authenticated
USING (
  EXISTS (
    SELECT 1 FROM user_roles
    WHERE user_id = auth.uid()
    AND role = 'admin'
  )
);
sql
-- Check user role for admin access
CREATE POLICY "Admins can do everything"
ON projects FOR ALL
TO authenticated
USING (
  EXISTS (
    SELECT 1 FROM user_roles
    WHERE user_id = auth.uid()
    AND role = 'admin'
  )
);

Service Role Bypass

服务角色绕过RLS

For server-side operations that need to bypass RLS:
typescript
import { createClient } from '@supabase/supabase-js';

// This bypasses RLS - use carefully!
const supabaseAdmin = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!, // Not ANON key!
  { auth: { persistSession: false } }
);
对于需要绕过RLS的服务器端操作:
typescript
import { createClient } from '@supabase/supabase-js';

// This bypasses RLS - use carefully!
const supabaseAdmin = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!, // Not ANON key!
  { auth: { persistSession: false } }
);

Testing Policies

测试策略

sql
-- Test as specific user
SET request.jwt.claim.sub = 'user-uuid-here';

-- Run query and check results
SELECT * FROM projects;

-- Reset
RESET request.jwt.claim.sub;
sql
-- Test as specific user
SET request.jwt.claim.sub = 'user-uuid-here';

-- Run query and check results
SELECT * FROM projects;

-- Reset
RESET request.jwt.claim.sub;

Security Checklist

安全检查清单

  • RLS enabled on all tables with user data
  • Service role key only on server, never client
  • Policies cover all operations (SELECT, INSERT, UPDATE, DELETE)
  • No policies use functions that could be exploited
  • Test policies with different user roles
  • 所有包含用户数据的表已启用RLS
  • 服务角色密钥仅部署在服务器端,绝不可暴露给客户端
  • 策略覆盖所有操作(SELECT、INSERT、UPDATE、DELETE)
  • 策略未使用存在被利用风险的函数
  • 针对不同用户角色测试策略