Exemplo de API utilizando o framework Express.js, construída com base no curso Iniciando no desenvolvimento de API Node.js com Typescript do professor Jorge Aluizio
- Executando
- Documentação da API (Swagger)
- Tópicos cobertos pelo projeto base
- Tópicos extras (complementares ao projeto base)
- Anotações
-
npm install
instale as dependências do projeto -
mv sample.env .env
preencha as variáveis de ambiente -
npm run typeorm migration:run
execute as migrações do banco de dados -
npm run seeding
crie o usuário admin -
npm run dev
inicie o servidor -
faça o login com o usuário admin à partir de uma requisição
POST
na rota/users/login
, enviando o email e o password. Você receberá o token de acesso no response e um cookierefresh-token
contento o token de atualização
// POST
{
"email": "user.admin@email.com",
"password": "12345678"
}
-
agora, antes de fazer as demais requisições basta adicionar ao Header o campo
Authorization
com o valorBearer + expaço + token de acesso
-
após expirar o token de acesso, utilize o token de atualização para gerar um novo token de acesso. Para isso, faça uma requisição
POST
na rota/users/login/refresh
enviando o cookierefresh-token
no headerCookie
. Você receberá um novo token de acesso e um novo token de atualização via cookies
// axios config example
const options = {
method: 'POST',
url: 'http://localhost:3000/api/v1/users/login/refresh',
headers: {
Cookie: 'refresh-token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NzcwOTQzMDcsImV4cCI6MTY3NzA5NzkwNywiYXVkIjoidXJuOmNsaWVudDphdWRpZW5jZTpyZWZyZXNoIiwiaXNzIjoidXJuOm15LWFwaS1leHByZXNzOmlzc3VlcjpyZWZyZXNoIn0.qAB6RtnKCdkGfMKh9fjM5bvM9hBwSejEO8FuxhvWVQ8; Expires=Wed, 22 Feb 2023 17:31:47 GMT; Path=/; Secure; HttpOnly; Domain=localhost',
'Content-Type': 'application/json'
},
}
npm run dev
inicie o servidor- http://localhost:3000/api/v1/docs acesse a documentação no browser
- API Restful NodeJS com ExpressJS e TypeScript
- TypeORM para bancos de dados relacional
- Documentação da API Restful com o Swagger (Open API)
- IoC e injeção de dependências com a lib tsyringe da Microsoft. Artigo sobre o uso de containers de injeção de dependências
- Upload local de imagens com Multer
- Autenticação com token de acesso Json Web Token (JWT) e Refresh Token
- Validação dos dados recebidos pela API usando o express-validator
- Middleware de tratamento de erros personalizado
- Seeds para popular uma tabela do banco de dados utilizando o módulo typeorm-extension (recomendado pelo TypeORM)
- Implementação de access token e refresh token seguindo o artigo "Usando Tokens JWT de forma Segura", escrito por Lucas Santos
- Tradução de mensagens de erro com i18n
- Testes unitários e end-to-end com Jest
- Salvar Refresh Token em banco de dados Redis (para ter um melhor desempenho ao invalidar Refresh Tokens antigos)
- Salvar avatar no Simple Storage Service (S3) da AWS
- NodeJS para produção
# cria uma migration
npm run typeorm migration:create src/shared/typeorm/migrations/CreateRolesTable
# executa as migrations
npm run typeorm migration:run
# mostra todas as migrations e se elas foram executadas ou não
npm run typeorm migration:show
# desfaz a última migration executada
npm run typeorm migration:revert
# exclui completamente os dados do banco de dados
npm run typeorm schema:drop
# popula a tabela de Roles com dados iniciais
npm run seeding
- Especificação AES (Advanced Encryption Standard)
- Pode utilizar uma ou duas chaves de encriptação
- Módulo ECB (Electronic Code Book), para utilizar apenas uma chave
openssl list-cipher-algorithms
- esse comando pode ser executado em sistemas baseados em Unix para verificar os tipos de algorítimos de criptografia disponíveis.openssl list-cipher-algorithms | grep "AES-256-ECB"
- Ferramenta para testar Criptografia
- Material de referência
No REPL, ou console do Node, é possível utilizar o módulo crypto
para gerar chaves aleatórias. Exemplo de uso: popular os campos que precisam de chaves no arquivo .env
node
entre no console do Nodecrypto.randomBytes(16).toString('hex')
crie uma chave aleatória mudando a quantidade de bytes de tamanho. Uma observação: o tamanho da chave sempre será o dobro do valor passado no parâmetro derandomBytes
, isso acontece por causa da conversão, para a base 16, que é feita em seguida pelotoString
. Para resolver esse problema basta construir o gerador nesse formatocrypto.randomBytes(Math.ceil(16)).toString('hex').slice(0, 16)