Na etapa anterior preparamos nosso banco de dados na nuvem. Agora vamos conectar nossa API Node.js + Express ao Supabase utilizando o SDK oficial @supabase/supabase-js e blindar nossas credenciais com variáveis de ambiente.
Abaixo está a sequência completa da nossa jornada. Primeiro construímos juntos o Projeto Base Guiado e, em seguida, cada estudante desenvolve seu projeto individual numerado.
Compreensão do ponto crítico de falha (chaves chumbadas no código) e funcionamento das variáveis de ambiente com o pacote SDK.
Instalação do @supabase/supabase-js e dotenv, coleta das chaves no painel da nuvem e blindagem com .gitignore.
Codificação ao vivo do arquivo src/config/supabaseClient.js e validação da ponte no server.js.
Escolha do exercício correspondente (01 a 32), criação da pasta exclusiva do sistema e inicialização do package.json.
Criação do .env personalizado com as variáveis específicas exigidas pelo tema sorteado e bloqueio no .gitignore.
Implementação do supabaseClient.js e da rota de diagnóstico da API Express retornando o status da conexão.
Execução do servidor no terminal, teste do endpoint de status no navegador e verificação do Checklist de Segurança.
Antes de escrever o código, entenda visualmente os 3 pilares que separam uma aplicação amadora e vulnerável de uma API profissional pronta para produção.
Colocar a chave do banco diretamente dentro do arquivo server.js expõe toda a sua infraestrutura. Se o código for enviado ao GitHub, robôs automatizados capturam sua chave instantaneamente.
O arquivo .env fica na raiz estrutural do projeto. Suas chaves devem ser escritas em LETRAS MAIÚSCULAS, sem espaços antes ou depois do sinal de igual (=) e sem aspas.
O arquivo .gitignore instrui o Git a ignorar completamente a pasta node_modules/ e o arquivo .env, mantendo seus segredos apenas na sua máquina local.
| Critério Técnico | ❌ Código Chumbado (Hardcoded) | ✅ Variáveis de Ambiente (.env + .gitignore) |
|---|---|---|
| Segurança no Repositório | Exposto publicamente no GitHub; qualquer pessoa pode clonar e acessar o banco. | Protegido localmente pelo .gitignore; nunca sobe para a nuvem de código. |
| Manutenção de Chaves | Exige caçar e alterar chaves manualmente em múltiplos arquivos .js. |
Alteração centralizada em um único arquivo de configuração fora do código-fonte. |
| Deploy em Produção | Requer novo commit no código toda vez que mudar do banco de Teste para Produção. | Troca instantânea via painel de hospedagem (Render, Railway, Vercel) sem tocar no código. |
Siga todos os 6 passos abaixo em conjunto para construir a arquitetura modelo de referência (Sistema Base de Controle de Acesso). Todos os códigos estão 100% completos e prontos para copiar e executar.
Project Settings (engrenagem) → API
📁 aula10-supabase-api/ ├── 📁 node_modules/ (ignorado) ├── 📁 src/ │ └── 📁 config/ │ └── 📄 supabaseClient.js ├── 🔒 .env (Cofre Secreto) ├── 🛡️ .gitignore (Escudo Git) ├── 📦 package.json └── 🚀 server.js (Entrada Express)
.env nunca vai para o GitHub.
supabaseClient.js centraliza e exporta uma única instância de conexão.
server.js consome o cliente já autenticado.
Teste uma linha do seu arquivo .env para verificar se ela respeita as 3 regras de segurança:
Execute no terminal integrado do VS Code (Ctrl + ')
Criamos a pasta do projeto, inicializamos o package.json e instalamos as três dependências fundamentais: o servidor express, o pacote dotenv (que lê o arquivo .env) e o SDK oficial @supabase/supabase-js.
mkdir aula10-supabase-api cd aula10-supabase-api npm init -y npm install express dotenv @supabase/supabase-js
package.jsonArquivo na raiz: package.json
Confira como deve ficar o seu package.json com o script start configurado para iniciar o arquivo server.js:
{
"name": "aula10-supabase-api",
"version": "1.0.0",
"description": "Conexao Segura API Express + Supabase Client com Cofre .env",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"@supabase/supabase-js": "^2.45.0",
"dotenv": "^16.4.5",
"express": "^4.19.2"
}
}
.env)Arquivo na raiz do projeto: .env
Crie um arquivo chamado exatamente .env (começando com ponto) na raiz do projeto. Substitua os valores abaixo pela Project URL e pela chave anon / public do seu projeto no Supabase:
PORT=3000 SUPABASE_URL=https://seu-id-do-projeto.supabase.co SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.cole_sua_chave_anon_publica_aqui AMBIENTE_EXECUCAO=desenvolvimento_seguro
.gitignore)Arquivo na raiz do projeto: .gitignore
Assim que criar o .env, crie imediatamente o arquivo .gitignore na raiz do projeto. Note que no VS Code o arquivo .env ficará acinzentado, provando que está protegido contra uploads acidentais:
# Ignorar pasta de pacotes pesados do Node.js node_modules/ # Ignorar rigorosamente o Cofre Digital de variaveis de ambiente .env .env.local .env.production # Ignorar logs do sistema npm-debug.log*
src/config/supabaseClient.js)Crie a pasta src/config e dentro dela o arquivo supabaseClient.js
Seguindo a arquitetura limpa, isolamos a conexão do banco em src/config/supabaseClient.js. Este módulo carrega os segredos via process.env, valida se eles existem e exporta a instância pronta para toda a aplicação:
// 1. Carrega as variáveis do arquivo .env para a memória (process.env)
require('dotenv').config();
// 2. Importa a função fábrica 'createClient' do SDK oficial do Supabase
const { createClient } = require('@supabase/supabase-js');
// 3. Resgata as credenciais de dentro do Cofre Digital (.env)
const supabaseUrl = process.env.SUPABASE_URL;
const supabaseKey = process.env.SUPABASE_KEY;
// 4. Validação de Segurança: impede que o servidor suba sem as chaves
if (!supabaseUrl || !supabaseKey) {
console.error('❌ [ERRO CRÍTICO DE SEGURANÇA]: SUPABASE_URL ou SUPABASE_KEY não encontradas no arquivo .env!');
console.error('Verifique se o arquivo .env está na raiz do projeto e sem espaços ao redor do sinal de =.');
process.exit(1);
}
// 5. Instancia a ponte oficial de comunicação com a nuvem do Supabase
const supabase = createClient(supabaseUrl, supabaseKey);
console.log('✅ [SUPABASE SDK]: Ponte de comunicação instanciada com segurança!');
// 6. Exporta a instância única para ser reutilizada em rotas e controllers
module.exports = supabase;
server.js)Arquivo na raiz do projeto: server.js
Agora conectamos nossa ponte ao server.js e criamos uma rota GET /api/status que comprova que o cliente do Supabase foi carregado sem jamais revelar a chave secreta na resposta JSON:
require('dotenv').config();
const express = require('express');
// Importa a ponte configurada e segura do Supabase
const supabase = require('./src/config/supabaseClient');
const app = express();
app.use(express.json());
const PORT = process.env.PORT || 3000;
// Rota principal de diagnóstico de segurança e conexão
app.get('/api/status', (req, res) => {
// Verifica se o objeto supabase possui os módulos internos carregados
const clienteAtivo = Boolean(supabase && supabase.auth && supabase.rest);
res.status(200).json({
sistema: "API Back-End I - Controle de Acesso",
status_servidor: "ONLINE",
ponte_supabase_sdk: clienteAtivo ? "CONECTADA" : "FALHA",
ambiente: process.env.AMBIENTE_EXECUCAO || "padrao",
seguranca_cofre_env: {
url_configurada: Boolean(process.env.SUPABASE_URL),
chave_protegida_no_cofre: Boolean(process.env.SUPABASE_KEY),
chave_exposta_no_codigo: false
},
mensagem: "Infraestrutura pronta para operações no banco na nuvem!"
});
});
app.listen(PORT, () => {
console.log('====================================================');
console.log(`🚀 Servidor Express rodando em: http://localhost:${PORT}`);
console.log(`🔍 Teste o status em: http://localhost:${PORT}/api/status`);
console.log('🔒 Inspecionando objeto Supabase Client no terminal:');
console.log(typeof supabase === 'object' ? 'Objeto Supabase instanciado com sucesso!' : 'Erro ao instanciar');
console.log('====================================================');
});
Selecione abaixo o card correspondente ao seu número (01 a 32). Cada projeto possui um domínio de negócio exclusivo, variáveis de ambiente específicas para o arquivo .env, tabela alvo no Supabase e rota personalizada de diagnóstico.