rochasalesseguros.com.br — Correção Login (Jun 2026)
Problema
Login do CMS/admin do site não funcionava. Conta tecrochasales@gmail.com não existia no banco e as tabelas do CMS estavam vazias.
Stack
- - Site:
rochasalesseguros.com.br— Next.js/TanStack Start, build Vite - - Auth + DB: Supabase self-hosted no VPS (Docker)
- - Docker Compose:
/docker/deploy-vps/docker-compose.yml - - Banco: PostgreSQL em
deploy-vps-db-1(porta 5433 externo, 5432 interno), databasepostgres - - Containers:
deploy-vps-kong-1,deploy-vps-auth-1,deploy-vps-db-1,deploy-vps-storage-1,deploy-vps-postgrest-1 - - Nginx: serve
/opt/rochasales/dist/emrochasalesseguros.com.br - - UUID:
a0107855-9650-47b0-80f1-d415d89b5c64 - - Role:
admin - - Auth metadata:
{ provider: "email", providers: ["password"] } - - Login admin:
tecrochasales@gmail.com/Rochasales2024 - - UUID admin:
a0107855-9650-47b0-80f1-d415d89b5c64 - - PostgreSQL: acesso via
docker exec deploy-vps-db-1 psql -U postgres -d postgres
Causa Raiz
1. Banco postgres em deploy-vps-db-1 estava sem tabelas (exceto schema_migrations)
2. GoTrue e PostgREST com JWT_SECRET divergentes → token de login passava na auth mas falhava na REST API (JWSInvalidSignature)
3. Role PostgreSQL admin não existia → token com role: admin no JWT não podia ser assumido
O que foi feito
1. Criar tabelas do CMS
`sql
-- Conectar ao banco (porta 5433)
docker exec deploy-vps-db-1 psql -U postgres -d postgres -c "SQL"
CREATE TABLE public.profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID UNIQUE NOT NULL,
email TEXT,
full_name TEXT,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE public.custom_roles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT UNIQUE NOT NULL,
has_admin_access BOOLEAN DEFAULT false,
can_manage_users BOOLEAN DEFAULT false,
can_manage_cms BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE public.user_roles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
role TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE public.cms_content (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title TEXT,
slug TEXT UNIQUE,
content JSONB DEFAULT '{}',
page TEXT,
is_published BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE public.broker_links (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID,
token TEXT UNIQUE,
folder_id TEXT,
client_id TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE public.tool_role_access (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
role_id UUID REFERENCES custom_roles(id),
tool_name TEXT,
access_level TEXT DEFAULT 'read',
created_at TIMESTAMPTZ DEFAULT now()
);
-- RLS
ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.custom_roles ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.user_roles ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.cms_content ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.broker_links ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.tool_role_access ENABLE ROW LEVEL SECURITY;
-- Políticas públicas (acesso total para desenvolvimento)
CREATE POLICY "profiles_all" ON public.profiles FOR ALL TO anon USING (true) WITH CHECK (true);
CREATE POLICY "custom_roles_all" ON public.custom_roles FOR ALL TO anon USING (true) WITH CHECK (true);
CREATE POLICY "user_roles_all" ON public.user_roles FOR ALL TO anon USING (true) WITH CHECK (true);
CREATE POLICY "cms_content_all" ON public.cms_content FOR ALL TO anon USING (true) WITH CHECK (true);
CREATE POLICY "broker_links_all" ON public.broker_links FOR ALL TO anon USING (true) WITH CHECK (true);
CREATE POLICY "tool_role_access_all" ON public.tool_role_access FOR ALL TO anon USING (true) WITH CHECK (true);
`
2. Criar role PostgreSQL admin
`sql
CREATE ROLE admin NOLOGIN;
GRANT ALL ON ALL TABLES IN SCHEMA public TO admin;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO admin;
-- Vincular ao authenticator
INSERT INTO pg_auth_members (roleid, member)
SELECT r.oid, a.oid FROM pg_roles r, pg_roles a
WHERE r.rolname = 'admin' AND a.rolname = 'authenticator';
`
3. Criar usuário admin no GoTrue
`bash
docker exec deploy-vps-auth-1 gotrue admin createuser --confirm --admin tecrochasales@gmail.com Rochasales2024
`
4. Inserir profile e roles
`sql
INSERT INTO public.profiles (user_id, email, full_name, is_active) VALUES
('a0107855-9650-47b0-80f1-d415d89b5c64', 'tecrochasales@gmail.com', 'TecRocha Sales', true);
INSERT INTO public.custom_roles (name, has_admin_access, can_manage_users, can_manage_cms) VALUES
('admin', true, true, true);
INSERT INTO public.user_roles (user_id, role) VALUES
('a0107855-9650-47b0-80f1-d415d89b5c64', 'admin');
`
5. Gerar nova anon key com secret correto
`python
import jwt, base64
secret = base64.b64decode('a0VUeHowQUJjZGVmZ2hpamtsbW5vcFFSc3R1dndhencxMjM0NTZBQmM9')
payload = {
"iss": "supabase", "ref": "rochasales", "role": "anon",
"iat": 1781618437, "exp": 2096978437
}
token = jwt.encode(payload, secret, algorithm='HS256')
print(token)
`
Nova anon key: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJvY2hhc2FsZXMiLCJyb2xlIjoiYW5vbiIsImlhdCI6MTc4MTYxODQzNywiZXhwIjoyMDk2OTc4NDM3fQ.v1g0gFbXzkBkNIqi4NEBSAaXPssn6Qy8LDmgpcmzV8c
6. Atualizar .env.production
`
VITE_SUPABASE_PUBLISHABLE_KEY=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJvY2hhc2FsZXMiLCJyb2xlIjoiYW5vbiIsImlhdCI6MTc4MTYxODQzNywiZXhwIjoyMDk2OTc4NDM3fQ.v1g0gFbXzkBkNIqi4NEBSAaXPssn6Qy8LDmgpcmzV8c
`
7. Rebuild do frontend
`bash
cd /opt/rochasales
PATH="/root/.nvm/versions/node/v20.20.2/bin:$PATH" nvm use 20
node ./node_modules/vite/bin/vite.js build
`
JWT Secrets — Informação Crítica
| Serviço | Secret (Base64) | Valor decodificado |
| --- | --- | --- |
GoTrue (GOTRUE_JWT_SECRET) | kETxz0ABcdefghijklmnopQRstuvwxyz123456ABc= | kETxz0ABcdefghijklmnopQRstuvwxyz123456ABc= |
PostgRest (PGRST_JWT_SECRET) | kETxz0JNJhJyg5UYxbd8zG6g2v9kXTYZGjY+3v7LUKI= | diferente! |
Os secrets DEVEM ser idênticos entre GoTrue e PostgREST/Kong para o login funcionar.
Para ver o secret de um container rodando:
`bash
docker exec deploy-vps-auth-1 printenv GOTRUE_JWT_SECRET
docker exec deploy-vps-postgrest-1 printenv PGRST_JWT_SECRET
`
Estado Atual (Jun 2026)
⚠️ Site fora do ar (502) — containers do /opt/rochasales/docker-compose.yml falharam ao subir porque o .env estava incompleto (faltando POSTGRES_PASSWORD, SMTP_*, etc.)
Para restaurar:
`bash
Usar a config que funcionava
cd /docker/deploy-vps
docker compose up -d
Verificar containers
docker ps --format "{{.Names}}\t{{.Status}}" | grep deploy-vps
Testar login
curl -X POST https://rochasalesseguros.com.br/auth/v1/token?grant_type=password \
-H "Content-Type: application/json" \
-H "apikey: NOVA_ANON_KEY" \
-d '{"email":"tecrochasales@gmail.com","password":"Rochasales2024"}'
`
⚠️ Não usar /opt/rochasales/.env — está incompleto e corrompido
Usar apenas /docker/deploy-vps/.env para subir os containers.
Credenciais
Tags
#rochasales #login #supabase-self-hosted #debug #cms