@fmlimao/create-esqueleto-login
v1.1.2
Published
Template para criar projetos baseados no Esqueleto Login - Sistema administrativo com autenticação e autorização
Downloads
12
Maintainers
Readme
🔐 Esqueleto Login
Esqueleto de sistema administrativo completo com autenticação e autorização baseada em perfis e privilégios. Projeto base para desenvolvimento de sistemas que necessitam de controle de acesso granular.
📋 Índice
- Funcionalidades
- Tecnologias
- Pré-requisitos
- Instalação
- Configuração
- Estrutura do Projeto
- Como Usar
- API REST
- Autenticação e Autorização
- Docker
- Estrutura de Banco de Dados
✨ Funcionalidades
🔑 Autenticação
- Login via Basic Auth (API) e formulário web
- Geração de tokens de sessão e acesso
- Gerenciamento de múltiplos tokens por usuário
- Cache de tokens no Redis para melhor performance
- Logout com revogação de tokens
- Expiração automática de tokens
🛡️ Autorização
- Sistema de perfis (roles) com suporte a perfil master
- Privilégios granulares (ex:
users.list,users.create,roles.update) - Middleware de autorização flexível:
- Verificação de privilégio único
- Múltiplos privilégios com lógica OR ou AND
- Bypass automático para perfis master
👥 Gerenciamento de Usuários
- CRUD completo de usuários
- Associação de usuários a perfis
- Controle de status (ativo/inativo)
- Soft delete
- Gerenciamento de tokens de acesso
🎭 Gerenciamento de Perfis
- CRUD completo de perfis
- Atribuição de privilégios aos perfis
- Perfis master com acesso total ao sistema
⚙️ Sistema de Configurações
- Gerenciamento de configurações do sistema via interface web
- Configurações agrupadas por categoria
- Suporte a múltiplos tipos de valores:
string- Texto simplesinteger- Números inteirosfloat- Números decimaisboolean- Valores verdadeiro/falsojson- Valores JSONselect- Seleção de opções pré-definidas
- Edição apenas de valores (não permite criar/deletar configurações)
- Configurações dinâmicas aplicadas em tempo real:
- THEME_SKIN - Skin do tema AdminLTE
- APP_TITLE - Título da aplicação
- APP_SHORT_TITLE - Título curto da aplicação
🌐 Duas Interfaces
- API REST (
/api/v1): Endpoints JSON para integração - Interface Web (
/): Views EJS para administração
🛠️ Tecnologias
- Node.js - Runtime JavaScript
- Express 5 - Framework web
- EJS - Template engine para views
- MySQL 8.0 - Banco de dados relacional
- Knex.js - Query builder para MySQL
- Redis - Cache e armazenamento de tokens
- bcrypt - Hash de senhas
- Helmet - Segurança HTTP
- ValidatorJS - Validação de dados
- Docker - Containerização
📦 Pré-requisitos
- Node.js (versão 18 ou superior)
- MySQL 8.0
- Redis 7
- Docker e Docker Compose (opcional, mas recomendado)
🚀 Instalação
Opção 1: Usar como Template NPM (Recomendado)
Após publicar no npm, você pode criar um novo projeto usando:
npm create @fmlimao/esqueleto-login meu-projetoPara testar antes de publicar, você pode clonar e executar:
git clone https://github.com/fmlimao/esqueleto-login.git temp-esqueleto
cd temp-esqueleto
node bin/create-esqueleto-login.js ../meu-projeto
cd ..
rm -rf temp-esqueletoO comando irá:
- ✅ Criar o diretório do projeto
- ✅ Copiar todos os arquivos necessários
- ✅ Instalar as dependências automaticamente
- ✅ Criar um arquivo
.env.exampleconfigurado
Depois, siga os passos 3 e 4 abaixo para configurar o banco de dados e variáveis de ambiente.
Opção 2: Instalação Manual
1. Clone o repositório
git clone <url-do-repositorio>
cd esqueleto-login2. Instale as dependências
cd app
npm install3. Configure o banco de dados
Execute o script SQL para criar as tabelas e dados iniciais:
mysql -u root -p < base.sqlOu importe o arquivo base.sql através de um cliente MySQL.
4. Configure as variáveis de ambiente
Crie um arquivo .env na pasta app/ com as seguintes variáveis:
# Aplicação
APP_HOST=http://localhost:3000
APP_PORT=3000
APP_TITLE=Esqueleto Login
APP_SHORT_TITLE=EL
# API
API_HOST=http://localhost:3000/api/v1
# Banco de Dados
DB_HOST=localhost
DB_PORT=3306
DB_NAME=esqueleto_login_demo
DB_USER=esqueleto_login_user
DB_PASS=esqueleto_login_pass
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
# Tokens
SESSION_TOKEN_EXPIRY_HOURS=8
MAX_ACCESS_TOKENS_PER_USER=10
TOKEN_CACHE_TTL_SECONDS=36005. Inicie a aplicação
node index.jsA aplicação estará disponível em http://localhost:3000
⚙️ Configuração
Variáveis de Ambiente
| Variável | Descrição | Padrão |
|----------|-----------|--------|
| APP_HOST | URL base da aplicação | - |
| APP_PORT | Porta do servidor | - |
| APP_TITLE | Título da aplicação (fallback se não encontrar no banco) | APP_TITLE |
| APP_SHORT_TITLE | Título curto (fallback se não encontrar no banco) | APP_SHORT_TITLE |
| API_HOST | URL base da API | http://192.168.0.210:3000/api/v1 |
| DB_HOST | Host do MySQL | - |
| DB_PORT | Porta do MySQL | - |
| DB_NAME | Nome do banco de dados | - |
| DB_USER | Usuário do MySQL | - |
| DB_PASS | Senha do MySQL | - |
| REDIS_HOST | Host do Redis | 192.168.0.210 |
| REDIS_PORT | Porta do Redis | 6379 |
| REDIS_PASSWORD | Senha do Redis (opcional) | - |
| SESSION_TOKEN_EXPIRY_HOURS | Horas até expiração do token de sessão | 8 |
| MAX_ACCESS_TOKENS_PER_USER | Máximo de tokens de acesso por usuário | 10 |
| TOKEN_CACHE_TTL_SECONDS | TTL do cache de tokens no Redis | 3600 |
Configurações do Sistema
Algumas configurações podem ser gerenciadas diretamente pela interface web em /settings (apenas usuários master):
- APP_TITLE - Título da aplicação (substitui a variável de ambiente)
- APP_SHORT_TITLE - Título curto da aplicação (substitui a variável de ambiente)
- THEME_SKIN - Skin do tema AdminLTE (ex:
skin-blue,skin-purple-light, etc.) - SESSION_TOKEN_EXPIRY_HOURS - Tempo de expiração dos tokens de sessão
- MAX_ACCESS_TOKENS_PER_USER - Máximo de tokens de acesso por usuário
- TOKEN_CACHE_TTL_SECONDS - TTL do cache de tokens no Redis
As configurações são aplicadas em tempo real, sem necessidade de reiniciar o servidor.
📁 Estrutura do Projeto
esqueleto-login/
├── app/
│ ├── src/
│ │ ├── controllers/
│ │ │ ├── api/v1/ # Controllers da API REST
│ │ │ │ ├── auth/ # Autenticação
│ │ │ │ ├── users/ # Usuários
│ │ │ │ ├── roles/ # Perfis
│ │ │ │ ├── privileges/ # Privilégios
│ │ │ │ └── settings/ # Configurações
│ │ │ └── app/v1/ # Controllers da interface web
│ │ │ └── settings/ # Configurações (web)
│ │ ├── database/
│ │ │ ├── conn.js # Conexão MySQL
│ │ │ └── redis.js # Conexão Redis
│ │ ├── helpers/ # Funções auxiliares
│ │ ├── middlewares/ # Middlewares Express
│ │ │ ├── authentication.js
│ │ │ └── authorization.js
│ │ ├── repositories/ # Camada de acesso a dados
│ │ ├── services/ # Serviços externos
│ │ └── views/ # Templates EJS
│ │ ├── layout/ # Layout base
│ │ ├── settings/ # Configurações
│ │ ├── users/ # Usuários
│ │ └── roles/ # Perfis
│ ├── index.js # Arquivo principal
│ └── package.json
├── base.sql # Script de criação do banco
├── docker-compose.yml # Configuração Docker
└── README.md🎯 Como Usar
Login Inicial
Após executar o base.sql, você terá um usuário master criado:
- Email:
[email protected] - Senha: (verifique no script SQL ou crie uma nova)
Interface Web
Acesse http://localhost:3000/login para fazer login na interface web.
Configurações do Sistema
Usuários com perfil master podem acessar /settings para gerenciar as configurações do sistema:
- APP_TITLE e APP_SHORT_TITLE - Títulos da aplicação
- THEME_SKIN - Skin do tema (ex:
skin-blue,skin-purple-light) - Configurações de tokens e cache
As alterações são aplicadas imediatamente, sem necessidade de reiniciar o servidor.
API REST
Para usar a API, primeiro faça login para obter um token:
curl -X POST http://localhost:3000/api/v1/auth/login \
-H "Authorization: Basic $(echo -n '[email protected]:senha' | base64)"Use o token retornado nas requisições subsequentes:
curl -X GET http://localhost:3000/api/v1/users \
-H "Authorization: Bearer SEU_TOKEN_AQUI"🔌 API REST
Autenticação
POST /api/v1/auth/login
Faz login e retorna um token de sessão.
Headers:
Authorization: Basic <base64(email:senha)>Resposta:
{
"error": false,
"code": 200,
"messages": ["Login realizado com sucesso."],
"content": {
"token": "token_aqui",
"tokenData": {
"uuid": "...",
"tokenType": "session",
"expiresAt": "...",
"createdAt": "..."
},
"user": {
"uuid": "...",
"name": "...",
"email": "...",
"role": {
"uuid": "...",
"name": "...",
"master": true
}
}
}
}GET /api/v1/auth/me
Retorna informações do usuário autenticado.
Headers:
Authorization: Bearer <token>POST /api/v1/auth/logout
Faz logout e revoga o token atual.
Headers:
Authorization: Bearer <token>Usuários
GET /api/v1/users- Lista usuários (requer:users.list)POST /api/v1/users- Cria usuário (requer:users.create)GET /api/v1/users/:uuid- Mostra usuário (requer:users.view)PUT /api/v1/users/:uuid- Atualiza usuário (requer:users.update)DELETE /api/v1/users/:uuid- Deleta usuário (requer:users.delete)
Tokens de Usuário
GET /api/v1/users/:uuid/tokens- Lista tokens do usuárioPOST /api/v1/users/:uuid/tokens- Cria token de acessoDELETE /api/v1/users/:uuid/tokens/:tokenUuid- Revoga token
Perfis
GET /api/v1/roles- Lista perfis (requer:roles.list)POST /api/v1/roles- Cria perfil (requer:roles.create)GET /api/v1/roles/:uuid- Mostra perfil (requer:roles.view)PUT /api/v1/roles/:uuid- Atualiza perfil (requer:roles.update)DELETE /api/v1/roles/:uuid- Deleta perfil (requer:roles.delete)
Privilégios de Perfis
GET /api/v1/roles/:uuid/privileges- Lista privilégios do perfilPOST /api/v1/roles/:uuid/privileges- Adiciona privilégio ao perfilDELETE /api/v1/roles/:uuid/privileges/:privilegeUuid- Remove privilégio do perfil
Privilégios
GET /api/v1/privileges- Lista todos os privilégios disponíveis
Configurações
GET /api/v1/settings/by-key/:keyName- Busca configuração por chave (público)GET /api/v1/settings- Lista todas as configurações agrupadas por categoria (requer: master)PUT /api/v1/settings/:uuid- Atualiza valor de uma configuração (requer: master)
🔐 Autenticação e Autorização
Autenticação
A autenticação é feita via Bearer Token no header Authorization:
Authorization: Bearer <seu_token>O token é validado através do middleware authentication.js, que:
- Extrai o token do header
- Gera o hash do token
- Busca no Redis (cache)
- Se não encontrar, busca no banco de dados
- Valida expiração
- Popula
req.userereq.userPrivileges
Autorização
A autorização é feita através do middleware authorization.js:
// Verifica um privilégio
authorization('users.list')
// Verifica múltiplos privilégios (OR - precisa ter pelo menos um)
authorization(['users.list', 'users.view'])
// Verifica múltiplos privilégios (AND - precisa ter todos)
authorization(['users.list', 'users.view'], { requireAll: true })
// Desabilita bypass para master
authorization('users.list', { allowMaster: false })Privilégios Disponíveis
users.list- Listar usuáriosusers.view- Ver usuáriousers.create- Criar usuáriousers.update- Atualizar usuáriousers.delete- Deletar usuárioroles.list- Listar perfisroles.view- Ver perfilroles.create- Criar perfilroles.update- Atualizar perfilroles.delete- Deletar perfilroles.privileges.list- Listar privilégios do perfilroles.privileges.add- Adicionar privilégio ao perfilroles.privileges.remove- Remover privilégio do perfilprivileges.list- Listar privilégios
Nota: O gerenciamento de configurações (/settings) requer perfil master. Futuramente será adicionado o privilégio settings.manage.
Perfil Master
Usuários com perfil master = true têm acesso total ao sistema, ignorando verificações de privilégios (exceto quando allowMaster: false).
🐳 Docker
O projeto inclui um docker-compose.yml para facilitar o desenvolvimento:
# Inicia os serviços (MySQL e Redis)
docker-compose up -d
# Para os serviços
docker-compose down
# Para os serviços e remove volumes
docker-compose down -vServiços
- MySQL: Porta
3306 - Redis: Porta
6379
🗄️ Estrutura de Banco de Dados
Tabelas Principais
users
Armazena os usuários do sistema.
id- ID únicouuid- UUID para identificação externaname- Nome do usuárioemail- Email (único)password- Hash da senha (bcrypt)role_id- ID do perfilactive- Status ativo/inativocreated_at,updated_at,deleted_at- Timestamps
roles
Armazena os perfis de acesso.
id- ID únicouuid- UUID para identificação externaname- Nome do perfildescription- Descriçãomaster- Flag de perfil mastercreated_at,updated_at,deleted_at- Timestamps
privileges
Armazena os privilégios disponíveis.
id- ID únicouuid- UUID para identificação externacategory- Categoria (ex: 'users', 'roles')name- Nome do privilégioslug- Slug único (ex: 'users.list')description- Descriçãocreated_at,updated_at,deleted_at- Timestamps
role_privileges
Tabela de relacionamento muitos-para-muitos entre perfis e privilégios.
role_id- ID do perfilprivilege_id- ID do privilégio
user_tokens
Armazena os tokens de autenticação.
id- ID únicouuid- UUID para identificação externauser_id- ID do usuáriotoken_hash- Hash do token (único)token_type- Tipo ('session' ou 'access')name- Nome do token (opcional)expires_at- Data de expiraçãolast_used_at- Último usorevoked_at- Data de revogaçãocreated_at,updated_at- Timestamps
settings
Armazena configurações do sistema.
id- ID únicouuid- UUID para identificação externacategory- Categoria da configuração (para agrupamento)key_name- Chave da configuração (único)type- Tipo do valor:string,integer,boolean,float,json,selectvalue- Valor da configuraçãovalues_options- Opções disponíveis (JSON array) - usado quandotype = 'select'description- Descrição da configuraçãocreated_at,updated_at- Timestamps
📝 Notas
- Todas as tabelas principais suportam soft delete através do campo
deleted_at - Tokens são armazenados com hash no banco e cache no Redis
- O sistema popula automaticamente o Redis com tokens válidos no startup
- Perfis master têm acesso total, ignorando verificações de privilégios
- Configurações do sistema (
APP_TITLE,APP_SHORT_TITLE,THEME_SKIN) são buscadas do banco de dados e aplicadas dinamicamente - As variáveis de ambiente
APP_TITLEeAPP_SHORT_TITLEservem apenas como fallback caso as configurações não sejam encontradas no banco
📦 Publicando no NPM
Este projeto pode ser usado como template npm. Para publicar:
1. Configure o package.json
O package.json na raiz já está configurado como template. Certifique-se de que:
- O nome do pacote está correto (
@fmlimao/create-esqueleto-login) - As informações de autor e repositório estão atualizadas
2. Faça login no npm
npm login3. Publique o pacote
npm publish --access publicImportante: Como você está usando um escopo (@fmlimao), você precisa adicionar --access public para tornar o pacote público. Sem isso, o pacote será privado (requer plano pago).
4. Teste o template
Após publicar, você pode testar criando um novo projeto:
npm create @fmlimao/esqueleto-login meu-projeto-testeComo funciona:
- O pacote se chama
@fmlimao/create-esqueleto-login - O comando para usar é
npm create @fmlimao/esqueleto-login - O npm remove automaticamente o prefixo
create-do nome do pacote
📄 Licença
ISC
