User Management com Node.js/ Mongo DB e Typescript

Ter um login e uma senha é algo praticamente indispensável no mundo digital, com um grande número de usuários se cadastrando, acaba sendo necessário ter um sistema gerenciador de usuários, ou seja, algo que armazene dados e ao mesmo tempo garanta que a sua senha está segura.
Sendo assim, diversas empresas acabam adicionando um sistema de gerenciamento de usuários, o que torna ter um projeto assim no seu portfólio muito vantajoso. Dessa maneira, o que é Gerenciamento de Usuários.

User Management
O User Management é uma função que nasceu com o objetivo de organizar os usuários e alterar permissões e informações de cada um. Essas funções de organização estão ficando cada vez mais avançadas e, comparado com antigamente, estão bem mais seguras com serviços de autenticação e testes de ponta a ponta.
Nesse artigo, iremos falar um pouco sobre gerenciamento de usuários veremos na prática como criar uma aplicação com Node.js, Typescript e MongoDB.
Quais funções criar no gerenciamento de usuários?
Os usuários estão acostumados a usar esse sistema de cadastro e login no seu dia a dia. Ou seja, o ato de registrar e entrar em sua conta deve ser algo simples e rápido.
Esse sistema normalmente tem funções de guardar informações do usuário, ter um sistema seguro de autenticação, permitir mudança de senha e ter autenticação de dois fatores.
Conceitos importantes
Um dos conceitos mais importantes para organizar os usuários é o User Roles. Esse conceito carrega a ideia de que os usuários podem ser divididos em diferentes áreas da empresa com permissões baseadas nas suas atividades, permissões de visitante ou permissões de administrador. É importante entender que quem vai definir essas regras é uma pessoa/empresa que tem em seu projeto a necessidade de se organizar por usuários.
Outro conceito essencial para organizar os usuários é o User Profile, devemos criar uma coleção de informações do usuário com dados como senha (criptografada), login, email, entre outras informações que a aplicação precisar.
Criando o backend para o Gerenciamento de usuários
Antes de criarmos os diretórios do projeto, devemos entender a estrutura do backend e como funcionará a comunicação entre os componentes criados. Observe a simplificação abaixo.
Observando o desenho acima podemos ver que normalmente o registro e entrada de usuários é disparado pelo frontend, porém, nesse artigo o foco será no backend da aplicação, parte responsável por se comunicar com o banco de dados e garantir que o usuário está autenticado.
Setup inicial de um projeto Typescript e MongoDB
Antes de começar a escrever código iremos criar o diretório principal do nosso projeto e instalar as dependências.
mkdir manage-users
cd manage-users
mkdir backend
cd backend
npm init -y
npm install -D typescript
npx tsx –init
O último comando usado é necessário para criamos o arquivo de configurações do Typescript, após criado podemos deixar ele desse jeito:
/manage-users/backend/tsconfig.json

npm install @typegoose/typegoose
npm install bcryptjs
npm install config
npm install cookie-parser
npm install dotenv
npm install express
npm install jsonwebtoken
npm install lodash
npm install mongoose
npm install redis
npm install ts-node-dev
npm install zod
npm install cors
Com as dependências instaladas, podemos criar o arquivo principal para iniciar a aplicação backend o app.ts. Esse arquivo será responsável por iniciar o servidor e consumir os endpoints da url que irão disparar as funções do backend. Além disso, ele também chama a função que conecta o servidor ao banco de dados.
mkdir src
cd src
touch app.ts
/manage-users/backend/src/app.ts


No arquivo anterior usamos uma coisa chamada de variáveis de ambiente. Elas ficam armazenadas no arquivo .env e podem ser criadas dessa maneira:
/manage-users/backend/.env

Vamos criar o arquivo de conexão com o banco de dados. Esse arquivo irá pegar as variáveis de ambiente do seu banco para fazer a conexão.
/manage-users/backend/Models/Connect.ts

Então criaremos o arquivo de conexão do servidor Redis, framework que facilita a criação de um sistema de gerenciamento de usuários muito usado para o armazenamento da estrutura de dados.
/manage-users/backend/Models/ConnectRedis.ts


E no último arquivo da pasta Models, será criado o arquivo userModel.ts, arquivo que criará a parte do banco de dados que armazenará os dados dos usuários cadastrados.
/manage-users/backend/Models/userModel.ts


Com isso, podemos começar a criar os serviços da aplicação, parte que faz efetivamente a comunicação do banco de dados com a aplicação. Nesse arquivo, faremos a parte da autenticação do token, algo que pode ser melhor exemplificado no desenho abaixo:
O JWT é responsável por criptografar a sua senha, garantindo a segurança de seus dados e permitindo que verifiquemos se a sua senha está correta, de acordo com a informação guardada no banco de dados.
/manage-users/backend/utils/Jwt.ts


Com isso, podemos criar o arquivo de serviços. Nele faremos as funções de criar um usuário, achá-lo pelo id, visualizar todos os usuários e cadastrar o token jwt.
/manage-users/backend/Services/userServices.ts


Terminando os serviços podemos partir para os Controllers, parte responsável trabalhar com as requisições e respostas. Nela iremos configurar as funções que futuramente serão usadas no endpoint.
/manage-users/backend/Controllers/userController.ts


/manage-users/backend/Controllers/authController.ts




No controller usado anteriormente, utilizamos uma função responsável por disparar um erro (essa função segue a seguinte estrutura):
/manage-users/backend/utils/ErrorResponse.ts


Após termos quase completado a arquitetura do software, podemos criar as rotas que usamos no arquivo app.ts criado inicialmente. Os arquivos de rotas são onde definimos o endpoint de cada requisição.
/manage-users/backend/routes/userRoute.ts

/manage-users/backend/routes/authRoute.ts


Por fim, podemos alterar o nosso package.json e finalmente testar a nossa aplicação. Dentro do package.json altere a chave script para isso:

Agora é só rodar o comando e testar as rotas criadas anteriormente. Recomendo o uso da extensão do VS Code Thunder Client.
npm start
Deverá ver uma mensagem assim:
Server started on port: 8000
Redis client connected...
Database connected...

Conclusão
Entender como funciona o gerenciamento de usuários é importante para qualquer desenvolvedor backend, porém é importante lembrar que, hoje em dia, a maioria dos serviços que precisam de autenticação acabam terceirizando o trabalho permitindo os usuários usarem suas contas da Google, ou do Github, o que acaba facilitando muito a vida do usuário.
Entendo que o desenvolvimento desse sistema serve mais para empresas que tem como objetivo controlar e organizar os funcionários de sua empresa de maneira mais assertiva.
Até logo!
A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.