202 lines
5.7 KiB
Markdown
202 lines
5.7 KiB
Markdown
# 🔐 Implementar RLS no Supabase - Guia Passo a Passo
|
||
|
||
## 📌 O que é RLS (Row Level Security)?
|
||
|
||
Row Level Security é um mecanismo de segurança no PostgreSQL que permite controlar qual linhas de dados cada usuário pode acessar. No nosso caso, garante que:
|
||
|
||
✅ **Usuário A** pode ver/editar apenas suas tarefas
|
||
✅ **Usuário B** pode ver/editar apenas suas tarefas
|
||
❌ **Usuário A NÃO** consegue acessar tarefas de **Usuário B**
|
||
|
||
## 🚀 Como Implementar no Supabase
|
||
|
||
### Passo 1: Acessar o SQL Editor do Supabase
|
||
|
||
1. Vá para [https://supabase.com/dashboard](https://supabase.com/dashboard)
|
||
2. Selecione seu projeto **"todolist-fullstack"**
|
||
3. No menu lateral, clique em **SQL Editor**
|
||
4. Clique em **New Query**
|
||
|
||
### Passo 2: Copiar o Script SQL
|
||
|
||
1. Abra o arquivo: `backend-api/SQL_TASKS_TABLE_RLS.sql`
|
||
2. Copie todo o conteúdo
|
||
3. Cole no editor SQL do Supabase
|
||
|
||
### Passo 3: Executar o Script
|
||
|
||
1. Clique no botão **▶️ RUN** (canto inferior direito)
|
||
2. Aguarde a execução completar (deve levar 2-5 segundos)
|
||
3. Verifique se não houve erros (aparecerá "Successfully" em verde)
|
||
|
||
### Passo 4: Verificar a Tabela Criada
|
||
|
||
1. Vá para **Database** → **Tables** no menu lateral
|
||
2. Você deve ver a tabela `tasks` listada
|
||
3. Clique nela para visualizar:
|
||
- Schema das colunas
|
||
- Índices criados
|
||
- Políticas RLS (abas "Row Level Security")
|
||
|
||
## 📋 O que o Script Cria
|
||
|
||
### 1️⃣ Tabela `tasks`
|
||
|
||
| Coluna | Tipo | Descrição |
|
||
|--------|------|-----------|
|
||
| `id` | UUID | ID único (auto-gerado) |
|
||
| `user_id` | UUID | Referência ao usuário (auth.users) |
|
||
| `title` | VARCHAR(255) | Título obrigatório |
|
||
| `description` | TEXT | Descrição opcional |
|
||
| `completed` | BOOLEAN | Status de conclusão |
|
||
| `due_date` | TIMESTAMP | Data de vencimento |
|
||
| `category` | VARCHAR(50) | Categoria para organização |
|
||
| `priority` | VARCHAR(20) | low \| medium \| high |
|
||
| `created_at` | TIMESTAMP | Auto-preenchido |
|
||
| `updated_at` | TIMESTAMP | Auto-atualizado |
|
||
|
||
### 2️⃣ Índices para Performance
|
||
|
||
```sql
|
||
idx_tasks_user_id -- Buscar tarefas por usuário
|
||
idx_tasks_completed -- Filtrar concluídas/pendentes
|
||
idx_tasks_created_at -- Ordenar por data de criação
|
||
idx_tasks_due_date -- Ordenar por vencimento
|
||
idx_tasks_user_completed -- Query combinada (comum)
|
||
```
|
||
|
||
### 3️⃣ Row Level Security (RLS) - 4 Políticas
|
||
|
||
#### ✅ SELECT - Ver tarefas próprias
|
||
```sql
|
||
auth.uid() = user_id
|
||
```
|
||
Usuário vê apenas suas tarefas.
|
||
|
||
#### ✅ INSERT - Criar tarefas próprias
|
||
```sql
|
||
auth.uid() = user_id
|
||
```
|
||
Usuário só consegue inserir tarefa com seu `user_id`.
|
||
|
||
#### ✅ UPDATE - Editar tarefas próprias
|
||
```sql
|
||
auth.uid() = user_id
|
||
```
|
||
Usuário só consegue atualizar suas tarefas.
|
||
|
||
#### ✅ DELETE - Deletar tarefas próprias
|
||
```sql
|
||
auth.uid() = user_id
|
||
```
|
||
Usuário só consegue deletar suas tarefas.
|
||
|
||
### 4️⃣ Trigger para `updated_at`
|
||
|
||
Atualiza o campo `updated_at` automaticamente toda vez que uma tarefa é modificada.
|
||
|
||
## 🧪 Testar a Implementação
|
||
|
||
### Teste 1: Verificar RLS Ativado
|
||
|
||
No SQL Editor, execute:
|
||
|
||
```sql
|
||
SELECT schemaname, tablename, rowsecurity
|
||
FROM pg_tables
|
||
WHERE tablename = 'tasks';
|
||
```
|
||
|
||
**Esperado:**
|
||
```
|
||
schemaname | tablename | rowsecurity
|
||
----------|-----------|-----------
|
||
public | tasks | true
|
||
```
|
||
|
||
### Teste 2: Listar Políticas RLS
|
||
|
||
```sql
|
||
SELECT tablename, policyname
|
||
FROM pg_policies
|
||
WHERE tablename = 'tasks'
|
||
ORDER BY policyname;
|
||
```
|
||
|
||
**Esperado:**
|
||
```
|
||
tablename | policyname
|
||
-----------|------------------------------------------
|
||
tasks | Users can create their own tasks
|
||
tasks | Users can delete their own tasks
|
||
tasks | Users can update their own tasks
|
||
tasks | Users can view their own tasks
|
||
```
|
||
|
||
### Teste 3: Testar Isolamento (via Supabase Dashboard)
|
||
|
||
1. Vá para **Authentication** → **Users** no dashboard
|
||
2. Crie 2 usuários de teste:
|
||
- `user1@test.com` / `password123`
|
||
- `user2@test.com` / `password123`
|
||
|
||
3. Autentique como `user1` no frontend
|
||
4. Crie uma tarefa para `user1`
|
||
5. Autentique como `user2` no frontend
|
||
6. Verifique que `user2` NÃO consegue ver a tarefa de `user1`
|
||
|
||
## ⚠️ Troubleshooting
|
||
|
||
### "Error: relation tasks does not exist"
|
||
- Verifique se você copiou o script inteiro
|
||
- Certifique-se de executar o script completo de uma vez
|
||
|
||
### "Error: policy already exists"
|
||
- Você está executando o script duas vezes
|
||
- Solução: Execute apenas uma vez ou delete as políticas primeiro
|
||
|
||
### RLS não está funcionando
|
||
- Verifique se RLS está **habilitado** (não desabilitado)
|
||
- Confirme que o `user_id` na tabela corresponde ao `auth.uid()` do usuário autenticado
|
||
|
||
## 🔗 Integração com Backend (NestJS)
|
||
|
||
O TasksService já está preparado para trabalhar com RLS:
|
||
|
||
```typescript
|
||
// O Supabase valida automaticamente:
|
||
// - Usuário só acessa suas tarefas (RLS)
|
||
// - Não consegue inserir tarefa com outro user_id
|
||
// - Não consegue atualizar/deletar tarefa de outro usuário
|
||
|
||
async findAll(userId: string) {
|
||
const { data, error } = await this.supabaseService
|
||
.getClient()
|
||
.from('tasks')
|
||
.select('*')
|
||
.eq('user_id', userId); // ← RLS já filtra automaticamente
|
||
|
||
return data;
|
||
}
|
||
```
|
||
|
||
## 📚 Referências Úteis
|
||
|
||
- 📖 [Supabase RLS Guide](https://supabase.com/docs/guides/auth/row-level-security)
|
||
- 🔒 [PostgreSQL Security](https://www.postgresql.org/docs/current/sql-altertable.html#SQL-ALTERTABLE-RLS)
|
||
- 🚀 [Best Practices](https://supabase.com/docs/guides/database/basics/best-practices)
|
||
|
||
## ✅ Próximos Passos
|
||
|
||
Após executar o script SQL:
|
||
|
||
1. ✅ Executar SQL no Supabase
|
||
2. ✅ Verificar tabela criada
|
||
3. ➡️ **Próximo**: Testar endpoints de tasks via Postman/Insomnia
|
||
4. ➡️ **Depois**: Implementar Frontend (Next.js)
|
||
|
||
---
|
||
|
||
**Status**: 🟡 Aguardando execução manual no Supabase
|
||
**Responsável**: Você (execute o SQL_TASKS_TABLE_RLS.sql no SQL Editor)
|