Autenticação em Node.js com Passport e PostgreSQL

Node.js

Autenticação em Node.js com Passport e PostgreSQL

Luiz Duarte
Escrito por Luiz Duarte em 20/02/2021
Junte-se a mais de 34 mil devs

Entre para minha lista e receba conteúdos exclusivos e com prioridade

Recentemente escrevi um tutorial ensinando como utilizar o Passport, uma popular lib JavaScript para construção de middlewares de autenticação. Neste tutorial, fiz toda a gestão de sessão e de autenticação em memória, usando um array simples, para fins didáticos.

A gestão de sessão não é incomum ser feita em memória, mas possivelmente você irá querer a gestão dos seus usuários persistida em um banco de dados, certo?

No tutorial de hoje, vamos adaptar o projeto anterior (então baixe ele na sua máquina) para uso com PostgreSQL, um popular banco de dados SQL.

Atenção: este é um tutorial intermediário. Parto do pressuposto aqui que você já conhece Node.js e PostgreSQL em níveis básicos e também que já realizou o tutorial anterior, onde criamos este projeto com persistência em array.

Para ver a construção de uma aplicação web completa usando Node.js e MySQL (perfeitamente compatível com PG também), conheça meu curso online e meu livro.

Curso FullStack

#1 – Configurando o banco de dados e variáveis de ambiente

Os dados de sessão dos usuários e os próprios usuários vão ficar armazenados em um banco PostgreSQL, substituindo o array do tutorial anterior.

Eu já expliquei tudo que você precisa saber sobre como configurar o ambiente PostgreSQL pra uso com Node neste tutorial.

Voltando ao nosso projeto Node.js, instale o driver do PostgreSQL para Node:

Note que instalei também o pacote dotenv-safe, que permitirá guardarmos variáveis de ambiente de uma maneira muito prática e profissional, permitindo fazer deploy do nosso projeto em produção sem ter de ficar trocando connection strings e coisas do tipo.

Para que o dotenv-safe funcione (ensino em videoaulas do meu curso de fullstack JS), você precisa criar dois arquivos novos: “.env” e “.env.example”. O “.env.example” é o template contendo quais variáveis de ambiente são obrigatórias para sua aplicação funcionar, em nosso caso, as abaixo:

Já o “.env”, contém a sua versão local das variáveis e o ideal é que você inclua no seu .gitignore o .env, para que ele não seja commitado em produção (em produção você deve setar as variáveis de ambiente de produção, e não vai querer elas sobrescritas de maneira alguma):

Agora vamos criar um módulo db.js, que vai fazer a gestão da conexão com o PostgreSQL. Crie-o na raiz do projeto.

Esta função apenas garante que teremos um único pool  de conexões com o banco de dados sendo reaproveitada em toda aplicação. Existem técnicas bem mais avançadas que isso, como usar um ORM por exemplo. Note que exportei a função ao final, para que quando este módulo for carregado a primeira vez, possamos criar a conexão.

Agora modifique o seu bin/www (geramos este projeto com o express-generator, lembra?) para que importe o nosso db.js e chame o connect:

Repare que eu encapsulei todo o conteúdo do bin/www em um IIFE. Isso foi necessário para conseguir usar async/await na conexão com o banco.

O objeto db possuirá as funções de manipulação com o banco e mesmo que a gente carregue ele em outros pontos da aplicação, ele usará o que já está em cache. Também coloquei como primeira linha o carregamento das variáveis de ambiente. Caso o .env não exista, teremos um erro. Caso não consiga se conectar ao banco, teremos um erro (certifique-se criar um banco com o nome ‘passport’ no seu PostgreSQL, ou mude a connection string de acordo). O projeto somente vai “subir” se estiver tudo 100%.

Se você rodar este projeto agora e tudo estiver 100%, você deve ver a mensagem no console de que a conexão foi bem sucedida.

Antes de prosseguirmos, é de bom tom cadastrarmos no mínimo um usuário em nosso banco de dados, para poder realizar os testes depois. Acesse o seu banco PostgreSQL local ou remoto e crie no banco ‘passport’, a tabela ‘users’, conforme SQL abaixo:

Depois, adicione nela um usuário com os seguintes dados:

Coloque no campo email, um email seu de verdade, pois precisaremos dele funcionando mais tarde. Note que o password do usuário está criptografado em formato de hash Bcrypt. Esta senha na verdade é o hash da palavra “123”. 🙂

Curso Node.js e MongoDB

#2 – Refatorando o app.js

Antes de mais nada, no nosso app.js nós definimos um secret que é usado pelo Passport para criptografar algumas coisas dele. Hoje este secret está chumbado, mas vamos mudar isso para usar uma variável de ambiente, como abaixo.

Além disso, vamos instalar uma nova dependência no projeto para que o express-session use o PostgreSQL ao invés da memória para gerenciar as sessões. O express-session é muito extensível e basta instalarmos o conector para o banco de dados apropriado e fazer umas poucas configurações.

No app.js, no mesmo bloco de configuração do Passport, carregue o middleware de sessão do connect-pg-simple e adicione-o na chamada do session, para que ele passe a apontar para o PostgreSQL corretamente.

Aqui estou carregando nosso módulo auth.js passando o objeto passport pra ele configurar a estratégia de autenticação. Depois digo para o express-session usar o connect-pg-simple que, sem configuração alguma, usa a variável de ambiente DATABASE_URL, e que os dados de sessão devem ser apagados automaticamente após 30 minutos.

Esse módulo espera que já exista uma tabela session criada no banco de dados. Você pode usar este script para fazê-lo, recomendado pelos criadores do pacote: https://github.com/voxpelli/node-connect-pg-simple/blob/HEAD/table.sql

#3 – Refatorando o auth.js

Agora que temos nosso banco rodando, vamos refatorar as partes do projeto que usavam o array em memória para fazer a gestão dos usuários para que usem nosso banco de dados. Vamos começar voltando ao nosso db.js e criando duas novas funções lá.

Agora, vamos abrir nosso auth.js, removendo o array de users, removendo as funções de findUser e findUserById originais e depois refatorando as duas chamadas das funções antigas para que usem as novas do objeto db, como abaixo.

Assim, ao invés de estarmos procurando em um array, estaremos procurando diretamente no banco de dados.

Como as funções do PostgreSQL são assíncronas, ou usamos callbacks, promises ou ainda async/await, que foi a opção que escolhi aqui. Devido a isso, tive de alterar as funções que chamam as findUser para que usem async/await.

E com isso você tem novamente a sua aplicação web em Node.js funcionando e exigindo autenticação, mas agora com o PostgreSQL como persistência de dados!

Quer aprender a publicar esta aplicação na Amazon? Dê uma olhada neste tutorial!

Ou então publique na Heroku, com este tutorial. 🙂

Quer aprender a construir aplicações web usando Node.js e MySQL (compatível com PG SQL) com a mesma didática deste tutorial? Conheça o meu curso online ou meu livro.

Olá, tudo bem?

O que você achou deste conteúdo? Conte nos comentários.

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *